mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 08:03:53 +08:00
fix(region): vendor update (#23367)
This commit is contained in:
7
go.mod
7
go.mod
@@ -27,7 +27,6 @@ require (
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible
|
||||
github.com/golang-plus/uuid v1.0.0
|
||||
github.com/golang/mock v1.4.4
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/google/cadvisor v0.38.5
|
||||
github.com/google/gopacket v1.1.17
|
||||
github.com/google/uuid v1.6.0
|
||||
@@ -97,14 +96,14 @@ require (
|
||||
k8s.io/cri-api v0.22.17
|
||||
k8s.io/klog/v2 v2.20.0
|
||||
moul.io/http2curl/v2 v2.3.0
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250915054625-7251d9eeceec
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250924031606-a2597eb1f66f
|
||||
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0
|
||||
yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1
|
||||
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
|
||||
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900
|
||||
yunion.io/x/pkg v1.10.4-0.20250820035218-6008459eb4f0
|
||||
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250902120005-3b18bc6371c7
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250923143347-b98e89dbc372
|
||||
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c
|
||||
)
|
||||
|
||||
@@ -206,6 +205,7 @@ require (
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-plus/errors v1.0.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/go-querystring v1.0.0 // indirect
|
||||
@@ -229,6 +229,7 @@ require (
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
|
||||
github.com/karrick/godirwalk v1.16.1 // indirect
|
||||
github.com/kr/fs v0.1.0 // indirect
|
||||
github.com/ks3sdklib/aws-sdk-go v1.8.1 // indirect
|
||||
github.com/leodido/go-urn v1.2.0 // indirect
|
||||
github.com/lestrrat-go/iter v0.0.0-20200422075355-fc1769541911 // indirect
|
||||
github.com/lestrrat-go/pdebug v0.0.0-20200204225717-4d6bd78da58d // indirect
|
||||
|
||||
10
go.sum
10
go.sum
@@ -588,6 +588,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/ks3sdklib/aws-sdk-go v1.8.1 h1:/3mYWujGfr4K/+mAdESbi9u3T4VDuHYMYFk1/OL0JWE=
|
||||
github.com/ks3sdklib/aws-sdk-go v1.8.1/go.mod h1:jGcsV0dJgMmStAyqjkKVUu6F167pAXYZAS3LqoZMmtM=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/lestrrat-go/iter v0.0.0-20200422075355-fc1769541911 h1:FvnrqecqX4zT0wOIbYK1gNgTm0677INEWiFY8UEYggY=
|
||||
@@ -1424,8 +1426,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250915054625-7251d9eeceec h1:GvDds+zC42TTTFoxui2/Y8mquJQKZ0ay858+/VabUlE=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250915054625-7251d9eeceec/go.mod h1:7P/TJZk8o4JjhFnF1nGZcsPg+sIpMoV0dWPPuG6yGLg=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250924031606-a2597eb1f66f h1:aLijaM2lCiOSvU4aMHKmViaHvi7xP3h0WNilHVVxXJg=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250924031606-a2597eb1f66f/go.mod h1:R5iP/4nGCluuekoa30B5hM/49IfPpGHXwFK3yT7m6Vw=
|
||||
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0 h1:msG4SiDSVU7CrXH06WuHlNEZXIooTcmNbfrIGHuIHBU=
|
||||
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
|
||||
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
|
||||
@@ -1443,7 +1445,7 @@ yunion.io/x/pkg v1.10.4-0.20250820035218-6008459eb4f0 h1:/vHcYqzQInxqR1jjS+e7A0o
|
||||
yunion.io/x/pkg v1.10.4-0.20250820035218-6008459eb4f0/go.mod h1:0Bwxqd9MA3ACi119/l02FprY/o9gHahmYC2bsSbnVpM=
|
||||
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1 h1:1KJ3YYinydPHpDEQRXdr/T8SYcKZ5Er+m489H+PnaQ4=
|
||||
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo=
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250902120005-3b18bc6371c7 h1:0OccQYkey6OsNUZNxd6CpCB/espBPnwlLT/gjl9YbXM=
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250902120005-3b18bc6371c7/go.mod h1:vCIZpqhZ5Jzaq3tFyrti/vv8BijQKtkzSgNT/uH4H5A=
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250923143347-b98e89dbc372 h1:8lR9HzYTxSgxcVv6uC2Ogkk1Y3FEEanABfgeleCzhfA=
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250923143347-b98e89dbc372/go.mod h1:vCIZpqhZ5Jzaq3tFyrti/vv8BijQKtkzSgNT/uH4H5A=
|
||||
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c h1:QuLab2kSRECZRxo4Lo2KcYn6XjQFDGaZ1+x0pYDVVwQ=
|
||||
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng=
|
||||
|
||||
@@ -185,11 +185,35 @@ func (p TimePoint) IsValids() bool {
|
||||
}
|
||||
|
||||
func (p TimePoint) Value() float64 {
|
||||
return *(p[0].(*float64))
|
||||
v := p[0]
|
||||
if fval, ok := v.(*float64); ok {
|
||||
return *fval
|
||||
}
|
||||
if ival, ok := v.(*int64); ok {
|
||||
return float64(*ival)
|
||||
}
|
||||
if t, ok := v.(float64); ok {
|
||||
return t
|
||||
}
|
||||
if t, ok := v.(int64); ok {
|
||||
return float64(t)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (p TimePoint) Timestamp() float64 {
|
||||
return p[len(p)-1].(float64)
|
||||
v := p[len(p)-1]
|
||||
if t, ok := v.(float64); ok {
|
||||
return t
|
||||
}
|
||||
if t, ok := v.(int64); ok {
|
||||
return float64(t)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (p TimePoint) Time() time.Time {
|
||||
return time.UnixMilli(int64(p.Timestamp()))
|
||||
}
|
||||
|
||||
func (p TimePoint) Values() []float64 {
|
||||
|
||||
@@ -30,7 +30,6 @@ import (
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/identity"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/logger"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/monitor"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/webconsole"
|
||||
)
|
||||
|
||||
@@ -565,63 +564,6 @@ func (self *SRegion) CreateInstance(hostId, hypervisor string, opts *cloudprovid
|
||||
return ins, self.create(&modules.Servers, input, ins)
|
||||
}
|
||||
|
||||
type SMetricData struct {
|
||||
Id string `json:"id"`
|
||||
Time time.Time `json:"time"`
|
||||
Value float64 `json:"value"`
|
||||
}
|
||||
|
||||
func (cli *SCloudpodsClient) GetMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
|
||||
brandArr := []string{"OneCloud"}
|
||||
metrics := []SMetricData{}
|
||||
usefulResourceType := []cloudprovider.TResourceType{cloudprovider.METRIC_RESOURCE_TYPE_HOST, cloudprovider.METRIC_RESOURCE_TYPE_SERVER}
|
||||
isUse, _ := utils.InArray(opts.ResourceType, usefulResourceType)
|
||||
if !isUse {
|
||||
return nil, nil
|
||||
}
|
||||
for i := 0; i < len(brandArr); i++ {
|
||||
params := map[string]interface{}{
|
||||
"metric_name": opts.MetricType,
|
||||
"start_time": opts.StartTime,
|
||||
"end_time": opts.EndTime,
|
||||
"interval": "1m",
|
||||
"tag_pairs": map[string]interface{}{
|
||||
"brand": brandArr[i],
|
||||
},
|
||||
}
|
||||
onecloudObj, err := monitor.UnifiedMonitorManager.Get(cli.s, "simple-query", jsonutils.Marshal(params))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tmp := []SMetricData{}
|
||||
onecloudObj.Unmarshal(&tmp, "values")
|
||||
metrics = append(metrics, tmp...)
|
||||
}
|
||||
|
||||
idWithMetric := map[string][]cloudprovider.MetricValue{}
|
||||
for _, v := range metrics {
|
||||
if _, isExist := idWithMetric[v.Id]; !isExist {
|
||||
idWithMetric[v.Id] = []cloudprovider.MetricValue{{
|
||||
Timestamp: v.Time,
|
||||
Value: v.Value}}
|
||||
} else {
|
||||
idWithMetric[v.Id] = append(idWithMetric[v.Id], cloudprovider.MetricValue{
|
||||
Timestamp: v.Time,
|
||||
Value: v.Value})
|
||||
}
|
||||
}
|
||||
|
||||
res := []cloudprovider.MetricValues{}
|
||||
for _, metric := range metrics {
|
||||
res = append(res, cloudprovider.MetricValues{
|
||||
Id: metric.Id,
|
||||
MetricType: opts.MetricType,
|
||||
Values: idWithMetric[metric.Id],
|
||||
})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (self *SInstance) CreateDisk(ctx context.Context, opts *cloudprovider.GuestDiskCreateOptions) (string, error) {
|
||||
diskIds := []string{}
|
||||
for _, disk := range self.DisksInfo {
|
||||
|
||||
131
pkg/mcclient/cloudpods/monitor.go
Normal file
131
pkg/mcclient/cloudpods/monitor.go
Normal file
@@ -0,0 +1,131 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cloudpods
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
monitorapi "yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/monitor"
|
||||
)
|
||||
|
||||
func (cli *SCloudpodsClient) GetMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
|
||||
usefulResourceType := []cloudprovider.TResourceType{cloudprovider.METRIC_RESOURCE_TYPE_HOST, cloudprovider.METRIC_RESOURCE_TYPE_SERVER}
|
||||
isUse, _ := utils.InArray(opts.ResourceType, usefulResourceType)
|
||||
if !isUse {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
info := strings.Split(string(opts.MetricType), ".")
|
||||
if len(info) != 2 {
|
||||
return nil, errors.Errorf("invalid metric type: %s", opts.MetricType)
|
||||
}
|
||||
measurement := info[0]
|
||||
field := info[1]
|
||||
from := fmt.Sprintf("now-%dm", int(time.Now().Sub(opts.StartTime).Minutes()))
|
||||
to := fmt.Sprintf("now-%dm", int(time.Now().Sub(opts.EndTime).Minutes()))
|
||||
|
||||
query := &monitorapi.AlertQuery{
|
||||
Model: monitorapi.MetricQuery{
|
||||
Database: "telegraf",
|
||||
Measurement: measurement,
|
||||
Selects: []monitorapi.MetricQuerySelect{
|
||||
{
|
||||
{
|
||||
Type: "field",
|
||||
Params: []string{field},
|
||||
},
|
||||
},
|
||||
},
|
||||
Tags: []monitorapi.MetricQueryTag{
|
||||
{
|
||||
Key: "brand",
|
||||
Operator: "=",
|
||||
Value: "OneCloud",
|
||||
},
|
||||
},
|
||||
},
|
||||
From: from,
|
||||
To: to,
|
||||
}
|
||||
|
||||
input := monitorapi.MetricQueryInput{
|
||||
From: from,
|
||||
To: to,
|
||||
Scope: "system",
|
||||
Interval: "1m",
|
||||
MetricQuery: []*monitorapi.AlertQuery{
|
||||
query,
|
||||
},
|
||||
SkipCheckSeries: true,
|
||||
}
|
||||
if cli.debug {
|
||||
input.ShowMeta = true
|
||||
}
|
||||
|
||||
data := jsonutils.Marshal(input).(*jsonutils.JSONDict)
|
||||
sum256 := sha256.Sum256([]byte(data.String()))
|
||||
data.Set("signature", jsonutils.NewString(fmt.Sprintf("%x", sum256)))
|
||||
resp, err := monitor.UnifiedMonitorManager.PerformClassAction(cli.s, "query", data)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "query metric")
|
||||
}
|
||||
|
||||
metrics := &monitorapi.MetricsQueryResult{}
|
||||
err = resp.Unmarshal(metrics)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "query metric Unmarshal")
|
||||
}
|
||||
|
||||
res := []cloudprovider.MetricValues{}
|
||||
for _, serie := range metrics.Series {
|
||||
if len(serie.Tags) == 0 || (len(serie.Tags["vm_id"]) == 0 && len(serie.Tags["host_id"]) == 0) {
|
||||
continue
|
||||
}
|
||||
id := serie.Tags["vm_id"]
|
||||
if len(id) == 0 {
|
||||
id = serie.Tags["host_id"]
|
||||
}
|
||||
metric := cloudprovider.MetricValues{
|
||||
Id: id,
|
||||
MetricType: opts.MetricType,
|
||||
Values: []cloudprovider.MetricValue{},
|
||||
}
|
||||
values := []cloudprovider.MetricValue{}
|
||||
for _, point := range serie.Points {
|
||||
if len(point) != 2 {
|
||||
continue
|
||||
}
|
||||
values = append(values, cloudprovider.MetricValue{
|
||||
Timestamp: point.Time(),
|
||||
Value: point.Value(),
|
||||
})
|
||||
}
|
||||
if len(values) == 0 {
|
||||
continue
|
||||
}
|
||||
metric.Values = values
|
||||
res = append(res, metric)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
package shell
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/util/shellutils"
|
||||
@@ -24,6 +26,12 @@ import (
|
||||
|
||||
func init() {
|
||||
shellutils.R(&cloudprovider.MetricListOptions{}, "metric-list", "List metrics in a namespace", func(cli *cloudpods.SRegion, args *cloudprovider.MetricListOptions) error {
|
||||
if args.StartTime.IsZero() {
|
||||
args.StartTime = time.Now().Add(-time.Minute * 10)
|
||||
}
|
||||
if args.EndTime.IsZero() {
|
||||
args.EndTime = time.Now().Add(-time.Minute * 1)
|
||||
}
|
||||
metrics, err := cli.GetClient().GetMetrics(args)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
202
vendor/github.com/ks3sdklib/aws-sdk-go/LICENSE.txt
generated
vendored
Normal file
202
vendor/github.com/ks3sdklib/aws-sdk-go/LICENSE.txt
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
105
vendor/github.com/ks3sdklib/aws-sdk-go/aws/awserr/error.go
generated
vendored
Normal file
105
vendor/github.com/ks3sdklib/aws-sdk-go/aws/awserr/error.go
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
// Package awserr represents API error interface accessors for the SDK.
|
||||
package awserr
|
||||
|
||||
// An Error wraps lower level errors with code, message and an original error.
|
||||
// The underlying concrete error type may also satisfy other interfaces which
|
||||
// can be to used to obtain more specific information about the error.
|
||||
//
|
||||
// Calling Error() or String() will always include the full information about
|
||||
// an error based on its underlying type.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// output, err := s3manage.Upload(svc, input, opts)
|
||||
// if err != nil {
|
||||
// if awsErr, ok := err.(awserr.Error); ok {
|
||||
// // Get error details
|
||||
// log.Println("Error:", err.Code(), err.Message())
|
||||
//
|
||||
// Prints out full error message, including original error if there was one.
|
||||
// log.Println("Error:", err.Error())
|
||||
//
|
||||
// // Get original error
|
||||
// if origErr := err.Err(); origErr != nil {
|
||||
// // operate on original error.
|
||||
// }
|
||||
// } else {
|
||||
// fmt.Println(err.Error())
|
||||
// }
|
||||
// }
|
||||
//
|
||||
type Error interface {
|
||||
// Satisfy the generic error interface.
|
||||
error
|
||||
|
||||
// Returns the short phrase depicting the classification of the error.
|
||||
Code() string
|
||||
|
||||
// Returns the error details message.
|
||||
Message() string
|
||||
|
||||
// Returns the original error if one was set. Nil is returned if not set.
|
||||
OrigErr() error
|
||||
}
|
||||
|
||||
// A RequestFailure is an interface to extract request failure information from
|
||||
// an Error such as the request ID of the failed request returned by a service.
|
||||
// RequestFailures may not always have a requestID value if the request failed
|
||||
// prior to reaching the service such as a connection error.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// output, err := s3manage.Upload(svc, input, opts)
|
||||
// if err != nil {
|
||||
// if reqerr, ok := err.(RequestFailure); ok {
|
||||
// log.Printf("Request failed", reqerr.Code(), reqerr.Message(), reqerr.RequestID())
|
||||
// } else {
|
||||
// log.Printf("Error:", err.Error()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Combined with awserr.Error:
|
||||
//
|
||||
// output, err := s3manage.Upload(svc, input, opts)
|
||||
// if err != nil {
|
||||
// if awsErr, ok := err.(awserr.Error); ok {
|
||||
// // Generic AWS Error with Code, Message, and original error (if any)
|
||||
// fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr())
|
||||
//
|
||||
// if reqErr, ok := err.(awserr.RequestFailure); ok {
|
||||
// // A service error occurred
|
||||
// fmt.Println(reqErr.StatusCode(), reqErr.RequestID())
|
||||
// }
|
||||
// } else {
|
||||
// fmt.Println(err.Error())
|
||||
// }
|
||||
// }
|
||||
//
|
||||
type RequestFailure interface {
|
||||
Error
|
||||
|
||||
// The status code of the HTTP response.
|
||||
StatusCode() int
|
||||
|
||||
// The request ID returned by the service for a request failure. This will
|
||||
// be empty if no request ID is available such as the request failed due
|
||||
// to a connection error.
|
||||
RequestID() string
|
||||
}
|
||||
|
||||
// New returns an Error object described by the code, message, and origErr.
|
||||
//
|
||||
// If origErr satisfies the Error interface it will not be wrapped within a new
|
||||
// Error object and will instead be returned.
|
||||
func New(code, message string, origErr error) Error {
|
||||
if e, ok := origErr.(Error); ok && e != nil {
|
||||
return e
|
||||
}
|
||||
return newBaseError(code, message, origErr)
|
||||
}
|
||||
|
||||
// NewRequestFailure returns a new request error wrapper for the given Error
|
||||
// provided.
|
||||
func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure {
|
||||
return newRequestError(err, statusCode, reqID)
|
||||
}
|
||||
135
vendor/github.com/ks3sdklib/aws-sdk-go/aws/awserr/types.go
generated
vendored
Normal file
135
vendor/github.com/ks3sdklib/aws-sdk-go/aws/awserr/types.go
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
package awserr
|
||||
|
||||
import "fmt"
|
||||
|
||||
// SprintError returns a string of the formatted error code.
|
||||
//
|
||||
// Both extra and origErr are optional. If they are included their lines
|
||||
// will be added, but if they are not included their lines will be ignored.
|
||||
func SprintError(code, message, extra string, origErr error) string {
|
||||
msg := fmt.Sprintf("%s: %s", code, message)
|
||||
if extra != "" {
|
||||
msg = fmt.Sprintf("%s\n\t%s", msg, extra)
|
||||
}
|
||||
if origErr != nil {
|
||||
msg = fmt.Sprintf("%s\ncaused by: %s", msg, origErr.Error())
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
// A baseError wraps the code and message which defines an error. It also
|
||||
// can be used to wrap an original error object.
|
||||
//
|
||||
// Should be used as the root for errors satisfying the awserr.Error. Also
|
||||
// for any error which does not fit into a specific error wrapper type.
|
||||
type baseError struct {
|
||||
// Classification of error
|
||||
code string
|
||||
|
||||
// Detailed information about error
|
||||
message string
|
||||
|
||||
// Optional original error this error is based off of. Allows building
|
||||
// chained errors.
|
||||
origErr error
|
||||
}
|
||||
|
||||
// newBaseError returns an error object for the code, message, and err.
|
||||
//
|
||||
// code is a short no whitespace phrase depicting the classification of
|
||||
// the error that is being created.
|
||||
//
|
||||
// message is the free flow string containing detailed information about the error.
|
||||
//
|
||||
// origErr is the error object which will be nested under the new error to be returned.
|
||||
func newBaseError(code, message string, origErr error) *baseError {
|
||||
return &baseError{
|
||||
code: code,
|
||||
message: message,
|
||||
origErr: origErr,
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns the string representation of the error.
|
||||
//
|
||||
// See ErrorWithExtra for formatting.
|
||||
//
|
||||
// Satisfies the error interface.
|
||||
func (b baseError) Error() string {
|
||||
return SprintError(b.code, b.message, "", b.origErr)
|
||||
}
|
||||
|
||||
// String returns the string representation of the error.
|
||||
// Alias for Error to satisfy the stringer interface.
|
||||
func (b baseError) String() string {
|
||||
return b.Error()
|
||||
}
|
||||
|
||||
// Code returns the short phrase depicting the classification of the error.
|
||||
func (b baseError) Code() string {
|
||||
return b.code
|
||||
}
|
||||
|
||||
// Message returns the error details message.
|
||||
func (b baseError) Message() string {
|
||||
return b.message
|
||||
}
|
||||
|
||||
// OrigErr returns the original error if one was set. Nil is returned if no error
|
||||
// was set.
|
||||
func (b baseError) OrigErr() error {
|
||||
return b.origErr
|
||||
}
|
||||
|
||||
// So that the Error interface type can be included as an anonymous field
|
||||
// in the requestError struct and not conflict with the error.Error() method.
|
||||
type awsError Error
|
||||
|
||||
// A requestError wraps a request or service error.
|
||||
//
|
||||
// Composed of baseError for code, message, and original error.
|
||||
type requestError struct {
|
||||
awsError
|
||||
statusCode int
|
||||
requestID string
|
||||
}
|
||||
|
||||
// newRequestError returns a wrapped error with additional information for request
|
||||
// status code, and service requestID.
|
||||
//
|
||||
// Should be used to wrap all request which involve service requests. Even if
|
||||
// the request failed without a service response, but had an HTTP status code
|
||||
// that may be meaningful.
|
||||
//
|
||||
// Also wraps original errors via the baseError.
|
||||
func newRequestError(err Error, statusCode int, requestID string) *requestError {
|
||||
return &requestError{
|
||||
awsError: err,
|
||||
statusCode: statusCode,
|
||||
requestID: requestID,
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns the string representation of the error.
|
||||
// Satisfies the error interface.
|
||||
func (r requestError) Error() string {
|
||||
extra := fmt.Sprintf("status code: %d, request id: [%s]",
|
||||
r.statusCode, r.requestID)
|
||||
return SprintError(r.Code(), r.Message(), extra, r.OrigErr())
|
||||
}
|
||||
|
||||
// String returns the string representation of the error.
|
||||
// Alias for Error to satisfy the stringer interface.
|
||||
func (r requestError) String() string {
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// StatusCode returns the wrapped status code for the error
|
||||
func (r requestError) StatusCode() int {
|
||||
return r.statusCode
|
||||
}
|
||||
|
||||
// RequestID returns the wrapped requestID
|
||||
func (r requestError) RequestID() string {
|
||||
return r.requestID
|
||||
}
|
||||
96
vendor/github.com/ks3sdklib/aws-sdk-go/aws/awsutil/copy.go
generated
vendored
Normal file
96
vendor/github.com/ks3sdklib/aws-sdk-go/aws/awsutil/copy.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
package awsutil
|
||||
|
||||
import (
|
||||
"io"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Copy deeply copies a src structure to dst. Useful for copying request and
|
||||
// response structures.
|
||||
//
|
||||
// Can copy between structs of different type, but will only copy fields which
|
||||
// are assignable, and exist in both structs. Fields which are not assignable,
|
||||
// or do not exist in both structs are ignored.
|
||||
func Copy(dst, src interface{}) {
|
||||
dstval := reflect.ValueOf(dst)
|
||||
if !dstval.IsValid() {
|
||||
panic("Copy dst cannot be nil")
|
||||
}
|
||||
|
||||
rcopy(dstval, reflect.ValueOf(src), true)
|
||||
}
|
||||
|
||||
// CopyOf returns a copy of src while also allocating the memory for dst.
|
||||
// src must be a pointer type or this operation will fail.
|
||||
func CopyOf(src interface{}) (dst interface{}) {
|
||||
dsti := reflect.New(reflect.TypeOf(src).Elem())
|
||||
dst = dsti.Interface()
|
||||
rcopy(dsti, reflect.ValueOf(src), true)
|
||||
return
|
||||
}
|
||||
|
||||
// rcopy performs a recursive copy of values from the source to destination.
|
||||
//
|
||||
// root is used to skip certain aspects of the copy which are not valid
|
||||
// for the root node of a object.
|
||||
func rcopy(dst, src reflect.Value, root bool) {
|
||||
if !src.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
switch src.Kind() {
|
||||
case reflect.Ptr:
|
||||
if _, ok := src.Interface().(io.Reader); ok {
|
||||
if dst.Kind() == reflect.Ptr && dst.Elem().CanSet() {
|
||||
dst.Elem().Set(src)
|
||||
} else if dst.CanSet() {
|
||||
dst.Set(src)
|
||||
}
|
||||
} else {
|
||||
e := src.Type().Elem()
|
||||
if dst.CanSet() && !src.IsNil() {
|
||||
dst.Set(reflect.New(e))
|
||||
}
|
||||
if src.Elem().IsValid() {
|
||||
// Keep the current root state since the depth hasn't changed
|
||||
rcopy(dst.Elem(), src.Elem(), root)
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
if !root {
|
||||
dst.Set(reflect.New(src.Type()).Elem())
|
||||
}
|
||||
|
||||
t := dst.Type()
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
name := t.Field(i).Name
|
||||
srcVal := src.FieldByName(name)
|
||||
dstVal := dst.FieldByName(name)
|
||||
if srcVal.IsValid() && dstVal.CanSet() {
|
||||
rcopy(dstVal, srcVal, false)
|
||||
}
|
||||
}
|
||||
case reflect.Slice:
|
||||
s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap())
|
||||
dst.Set(s)
|
||||
for i := 0; i < src.Len(); i++ {
|
||||
rcopy(dst.Index(i), src.Index(i), false)
|
||||
}
|
||||
case reflect.Map:
|
||||
s := reflect.MakeMap(src.Type())
|
||||
dst.Set(s)
|
||||
for _, k := range src.MapKeys() {
|
||||
v := src.MapIndex(k)
|
||||
v2 := reflect.New(v.Type()).Elem()
|
||||
rcopy(v2, v, false)
|
||||
dst.SetMapIndex(k, v2)
|
||||
}
|
||||
default:
|
||||
// Assign the value if possible. If its not assignable, the value would
|
||||
// need to be converted and the impact of that may be unexpected, or is
|
||||
// not compatible with the dst type.
|
||||
if src.Type().AssignableTo(dst.Type()) {
|
||||
dst.Set(src)
|
||||
}
|
||||
}
|
||||
}
|
||||
175
vendor/github.com/ks3sdklib/aws-sdk-go/aws/awsutil/path_value.go
generated
vendored
Normal file
175
vendor/github.com/ks3sdklib/aws-sdk-go/aws/awsutil/path_value.go
generated
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
package awsutil
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var indexRe = regexp.MustCompile(`(.+)\[(-?\d+)?\]$`)
|
||||
|
||||
// rValuesAtPath returns a slice of values found in value v. The values
|
||||
// in v are explored recursively so all nested values are collected.
|
||||
func rValuesAtPath(v interface{}, path string, create bool, caseSensitive bool) []reflect.Value {
|
||||
pathparts := strings.Split(path, "||")
|
||||
if len(pathparts) > 1 {
|
||||
for _, pathpart := range pathparts {
|
||||
vals := rValuesAtPath(v, pathpart, create, caseSensitive)
|
||||
if vals != nil && len(vals) > 0 {
|
||||
return vals
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
values := []reflect.Value{reflect.Indirect(reflect.ValueOf(v))}
|
||||
components := strings.Split(path, ".")
|
||||
for len(values) > 0 && len(components) > 0 {
|
||||
var index *int64
|
||||
var indexStar bool
|
||||
c := strings.TrimSpace(components[0])
|
||||
if c == "" { // no actual component, illegal syntax
|
||||
return nil
|
||||
} else if caseSensitive && c != "*" && strings.ToLower(c[0:1]) == c[0:1] {
|
||||
// TODO normalize case for user
|
||||
return nil // don't support unexported fields
|
||||
}
|
||||
|
||||
// parse this component
|
||||
if m := indexRe.FindStringSubmatch(c); m != nil {
|
||||
c = m[1]
|
||||
if m[2] == "" {
|
||||
index = nil
|
||||
indexStar = true
|
||||
} else {
|
||||
i, _ := strconv.ParseInt(m[2], 10, 32)
|
||||
index = &i
|
||||
indexStar = false
|
||||
}
|
||||
}
|
||||
|
||||
nextvals := []reflect.Value{}
|
||||
for _, value := range values {
|
||||
// pull component name out of struct member
|
||||
if value.Kind() != reflect.Struct {
|
||||
continue
|
||||
}
|
||||
|
||||
if c == "*" { // pull all members
|
||||
for i := 0; i < value.NumField(); i++ {
|
||||
if f := reflect.Indirect(value.Field(i)); f.IsValid() {
|
||||
nextvals = append(nextvals, f)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
value = value.FieldByNameFunc(func(name string) bool {
|
||||
if c == name {
|
||||
return true
|
||||
} else if !caseSensitive && strings.ToLower(name) == strings.ToLower(c) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
if create && value.Kind() == reflect.Ptr && value.IsNil() {
|
||||
value.Set(reflect.New(value.Type().Elem()))
|
||||
value = value.Elem()
|
||||
} else {
|
||||
value = reflect.Indirect(value)
|
||||
}
|
||||
|
||||
if value.IsValid() {
|
||||
nextvals = append(nextvals, value)
|
||||
}
|
||||
}
|
||||
values = nextvals
|
||||
|
||||
if indexStar || index != nil {
|
||||
nextvals = []reflect.Value{}
|
||||
for _, value := range values {
|
||||
value := reflect.Indirect(value)
|
||||
if value.Kind() != reflect.Slice {
|
||||
continue
|
||||
}
|
||||
|
||||
if indexStar { // grab all indices
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
idx := reflect.Indirect(value.Index(i))
|
||||
if idx.IsValid() {
|
||||
nextvals = append(nextvals, idx)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// pull out index
|
||||
i := int(*index)
|
||||
if i >= value.Len() { // check out of bounds
|
||||
if create {
|
||||
// TODO resize slice
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
} else if i < 0 { // support negative indexing
|
||||
i = value.Len() + i
|
||||
}
|
||||
value = reflect.Indirect(value.Index(i))
|
||||
|
||||
if value.IsValid() {
|
||||
nextvals = append(nextvals, value)
|
||||
}
|
||||
}
|
||||
values = nextvals
|
||||
}
|
||||
|
||||
components = components[1:]
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
// ValuesAtPath returns a list of objects at the lexical path inside of a structure
|
||||
func ValuesAtPath(i interface{}, path string) []interface{} {
|
||||
if rvals := rValuesAtPath(i, path, false, true); rvals != nil {
|
||||
vals := make([]interface{}, len(rvals))
|
||||
for i, rval := range rvals {
|
||||
vals[i] = rval.Interface()
|
||||
}
|
||||
return vals
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValuesAtAnyPath returns a list of objects at the case-insensitive lexical
|
||||
// path inside of a structure
|
||||
func ValuesAtAnyPath(i interface{}, path string) []interface{} {
|
||||
if rvals := rValuesAtPath(i, path, false, false); rvals != nil {
|
||||
vals := make([]interface{}, len(rvals))
|
||||
for i, rval := range rvals {
|
||||
vals[i] = rval.Interface()
|
||||
}
|
||||
return vals
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetValueAtPath sets an object at the lexical path inside of a structure
|
||||
func SetValueAtPath(i interface{}, path string, v interface{}) {
|
||||
if rvals := rValuesAtPath(i, path, true, true); rvals != nil {
|
||||
for _, rval := range rvals {
|
||||
rval.Set(reflect.ValueOf(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetValueAtAnyPath sets an object at the case insensitive lexical path inside
|
||||
// of a structure
|
||||
func SetValueAtAnyPath(i interface{}, path string, v interface{}) {
|
||||
if rvals := rValuesAtPath(i, path, true, false); rvals != nil {
|
||||
for _, rval := range rvals {
|
||||
rval.Set(reflect.ValueOf(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
103
vendor/github.com/ks3sdklib/aws-sdk-go/aws/awsutil/string_value.go
generated
vendored
Normal file
103
vendor/github.com/ks3sdklib/aws-sdk-go/aws/awsutil/string_value.go
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
package awsutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// StringValue returns the string representation of a value.
|
||||
func StringValue(i interface{}) string {
|
||||
var buf bytes.Buffer
|
||||
stringValue(reflect.ValueOf(i), 0, &buf)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// stringValue will recursively walk value v to build a textual
|
||||
// representation of the value.
|
||||
func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) {
|
||||
for v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
switch v.Kind() {
|
||||
case reflect.Struct:
|
||||
strtype := v.Type().String()
|
||||
if strtype == "time.Time" {
|
||||
fmt.Fprintf(buf, "%s", v.Interface())
|
||||
break
|
||||
} else if strings.HasPrefix(strtype, "io.") {
|
||||
buf.WriteString("<buffer>")
|
||||
break
|
||||
}
|
||||
|
||||
buf.WriteString("{\n")
|
||||
|
||||
names := []string{}
|
||||
for i := 0; i < v.Type().NumField(); i++ {
|
||||
name := v.Type().Field(i).Name
|
||||
f := v.Field(i)
|
||||
if name[0:1] == strings.ToLower(name[0:1]) {
|
||||
continue // ignore unexported fields
|
||||
}
|
||||
if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() {
|
||||
continue // ignore unset fields
|
||||
}
|
||||
names = append(names, name)
|
||||
}
|
||||
|
||||
for i, n := range names {
|
||||
val := v.FieldByName(n)
|
||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
||||
buf.WriteString(n + ": ")
|
||||
stringValue(val, indent+2, buf)
|
||||
|
||||
if i < len(names)-1 {
|
||||
buf.WriteString(",\n")
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
||||
case reflect.Slice:
|
||||
nl, id, id2 := "", "", ""
|
||||
if v.Len() > 3 {
|
||||
nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
|
||||
}
|
||||
buf.WriteString("[" + nl)
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
buf.WriteString(id2)
|
||||
stringValue(v.Index(i), indent+2, buf)
|
||||
|
||||
if i < v.Len()-1 {
|
||||
buf.WriteString("," + nl)
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString(nl + id + "]")
|
||||
case reflect.Map:
|
||||
buf.WriteString("{\n")
|
||||
|
||||
for i, k := range v.MapKeys() {
|
||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
||||
buf.WriteString(k.String() + ": ")
|
||||
stringValue(v.MapIndex(k), indent+2, buf)
|
||||
|
||||
if i < v.Len()-1 {
|
||||
buf.WriteString(",\n")
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
||||
default:
|
||||
format := "%v"
|
||||
switch v.Interface().(type) {
|
||||
case string:
|
||||
format = "%q"
|
||||
case io.ReadSeeker, io.Reader:
|
||||
format = "buffer(%p)"
|
||||
}
|
||||
fmt.Fprintf(buf, format, v.Interface())
|
||||
}
|
||||
}
|
||||
151
vendor/github.com/ks3sdklib/aws-sdk-go/aws/awsutil/util.go
generated
vendored
Normal file
151
vendor/github.com/ks3sdklib/aws-sdk-go/aws/awsutil/util.go
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
package awsutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/xml/xmlutil"
|
||||
"go/format"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GoFmt returns the Go formated string of the input.
|
||||
//
|
||||
// Panics if the format fails.
|
||||
func GoFmt(buf string) string {
|
||||
formatted, err := format.Source([]byte(buf))
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("%s\nOriginal code:\n%s", err.Error(), buf))
|
||||
}
|
||||
return string(formatted)
|
||||
}
|
||||
|
||||
var reTrim = regexp.MustCompile(`\s{2,}`)
|
||||
|
||||
// Trim removes all leading and trailing white space.
|
||||
//
|
||||
// All consecutive spaces will be reduced to a single space.
|
||||
func Trim(s string) string {
|
||||
return strings.TrimSpace(reTrim.ReplaceAllString(s, " "))
|
||||
}
|
||||
|
||||
// Capitalize capitalizes the first character of the string.
|
||||
func Capitalize(s string) string {
|
||||
if len(s) == 1 {
|
||||
return strings.ToUpper(s)
|
||||
}
|
||||
return strings.ToUpper(s[0:1]) + s[1:]
|
||||
}
|
||||
|
||||
// SortXML sorts the reader's XML elements
|
||||
func SortXML(r io.Reader) string {
|
||||
var buf bytes.Buffer
|
||||
d := xml.NewDecoder(r)
|
||||
root, _ := xmlutil.XMLToStruct(d, nil)
|
||||
e := xml.NewEncoder(&buf)
|
||||
xmlutil.StructToXML(e, root, true)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// PrettyPrint generates a human readable representation of the value v.
|
||||
// All values of v are recursively found and pretty printed also.
|
||||
func PrettyPrint(v interface{}) string {
|
||||
value := reflect.ValueOf(v)
|
||||
switch value.Kind() {
|
||||
case reflect.Struct:
|
||||
str := fullName(value.Type()) + "{\n"
|
||||
for i := 0; i < value.NumField(); i++ {
|
||||
l := string(value.Type().Field(i).Name[0])
|
||||
if strings.ToUpper(l) == l {
|
||||
str += value.Type().Field(i).Name + ": "
|
||||
str += PrettyPrint(value.Field(i).Interface())
|
||||
str += ",\n"
|
||||
}
|
||||
}
|
||||
str += "}"
|
||||
return str
|
||||
case reflect.Map:
|
||||
str := "map[" + fullName(value.Type().Key()) + "]" + fullName(value.Type().Elem()) + "{\n"
|
||||
for _, k := range value.MapKeys() {
|
||||
str += "\"" + k.String() + "\": "
|
||||
str += PrettyPrint(value.MapIndex(k).Interface())
|
||||
str += ",\n"
|
||||
}
|
||||
str += "}"
|
||||
return str
|
||||
case reflect.Ptr:
|
||||
if e := value.Elem(); e.IsValid() {
|
||||
return "&" + PrettyPrint(e.Interface())
|
||||
}
|
||||
return "nil"
|
||||
case reflect.Slice:
|
||||
str := "[]" + fullName(value.Type().Elem()) + "{\n"
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
str += PrettyPrint(value.Index(i).Interface())
|
||||
str += ",\n"
|
||||
}
|
||||
str += "}"
|
||||
return str
|
||||
default:
|
||||
return fmt.Sprintf("%#v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func pkgName(t reflect.Type) string {
|
||||
pkg := t.PkgPath()
|
||||
c := strings.Split(pkg, "/")
|
||||
return c[len(c)-1]
|
||||
}
|
||||
|
||||
func fullName(t reflect.Type) string {
|
||||
if pkg := pkgName(t); pkg != "" {
|
||||
return pkg + "." + t.Name()
|
||||
}
|
||||
return t.Name()
|
||||
}
|
||||
|
||||
//获取指定目录及所有子目录下的所有文件,可以匹配后缀过滤。
|
||||
func WalkDir(dirPth, suffix string) (files []string, err error) {
|
||||
files = make([]string, 0, 30)
|
||||
suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写
|
||||
|
||||
err = filepath.Walk(dirPth, func(filename string, fi os.FileInfo, err error) error { //遍历目录
|
||||
//if err != nil { //忽略错误
|
||||
// return err
|
||||
//}
|
||||
|
||||
if fi.IsDir() { // 忽略目录
|
||||
return nil
|
||||
}
|
||||
|
||||
if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) {
|
||||
files = append(files, filename)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
return files, err
|
||||
}
|
||||
func IsHidden(path string) bool {
|
||||
fileInfo, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return fileInfo.Name()[0] == '.'
|
||||
}
|
||||
func ComputeMD5Hash(input []byte) []byte {
|
||||
h := md5.New()
|
||||
h.Write(input)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func EncodeAsString(bytes []byte) string {
|
||||
return base64.StdEncoding.EncodeToString(bytes)
|
||||
}
|
||||
303
vendor/github.com/ks3sdklib/aws-sdk-go/aws/config.go
generated
vendored
Normal file
303
vendor/github.com/ks3sdklib/aws-sdk-go/aws/config.go
generated
vendored
Normal file
@@ -0,0 +1,303 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/retry"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/credentials"
|
||||
)
|
||||
|
||||
// DefaultChainCredentials is a Credentials which will find the first available
|
||||
// credentials Value from the list of Providers.
|
||||
//
|
||||
// This should be used in the default case. Once the type of credentials are
|
||||
// known switching to the specific Credentials will be more efficient.
|
||||
var DefaultChainCredentials = credentials.NewChainCredentials(
|
||||
[]credentials.Provider{
|
||||
&credentials.EnvProvider{},
|
||||
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
|
||||
&credentials.EC2RoleProvider{ExpiryWindow: 5 * time.Minute},
|
||||
})
|
||||
|
||||
// DefaultMaxRetries is the default number of retries for a service.
|
||||
const DefaultMaxRetries = 3
|
||||
|
||||
// DefaultConfig is the default all service configuration will be based off of.
|
||||
var DefaultConfig = &Config{
|
||||
Credentials: DefaultChainCredentials,
|
||||
Endpoint: "",
|
||||
Ks3BillEndpoint: "ks3bill.api.ksyun.com",
|
||||
Region: "",
|
||||
DisableSSL: false,
|
||||
ManualSend: false,
|
||||
HTTPClient: http.DefaultClient,
|
||||
LogHTTPBody: false,
|
||||
LogLevel: Off,
|
||||
Logger: os.Stdout,
|
||||
MaxRetries: DefaultMaxRetries,
|
||||
RetryRule: retry.DefaultExponentialRetryRule,
|
||||
ShouldRetry: retry.ShouldRetry,
|
||||
DisableParamValidation: false,
|
||||
DisableComputeChecksums: false,
|
||||
S3ForcePathStyle: false,
|
||||
DomainMode: false,
|
||||
SignerVersion: "V2",
|
||||
CrcCheckEnabled: false,
|
||||
DisableRestProtocolURICleaning: true,
|
||||
DisableDnsCache: false,
|
||||
}
|
||||
|
||||
// A Config provides service configuration
|
||||
type Config struct {
|
||||
Credentials *credentials.Credentials
|
||||
Endpoint string
|
||||
Ks3BillEndpoint string
|
||||
Region string
|
||||
DisableSSL bool
|
||||
ManualSend bool
|
||||
HTTPClient *http.Client
|
||||
LogHTTPBody bool
|
||||
LogLevel uint
|
||||
Logger io.Writer
|
||||
MaxRetries int // 重试次数
|
||||
RetryRule retry.RetryRule // 重试规则
|
||||
ShouldRetry func(error) bool // 是否需要重试
|
||||
DisableParamValidation bool
|
||||
DisableComputeChecksums bool
|
||||
S3ForcePathStyle bool
|
||||
DomainMode bool
|
||||
SignerVersion string
|
||||
CrcCheckEnabled bool // 允许crc64校验,默认为false
|
||||
DisableRestProtocolURICleaning bool // 禁用path clean,默认为true
|
||||
DisableDnsCache bool // 禁用DNS缓存,默认为false
|
||||
}
|
||||
|
||||
// Copy will return a shallow copy of the Config object.
|
||||
func (c Config) Copy() Config {
|
||||
dst := Config{}
|
||||
dst.Credentials = c.Credentials
|
||||
dst.Endpoint = c.Endpoint
|
||||
dst.Ks3BillEndpoint = c.Ks3BillEndpoint
|
||||
dst.Region = c.Region
|
||||
dst.DisableSSL = c.DisableSSL
|
||||
dst.ManualSend = c.ManualSend
|
||||
dst.HTTPClient = c.HTTPClient
|
||||
dst.LogHTTPBody = c.LogHTTPBody
|
||||
dst.LogLevel = c.LogLevel
|
||||
dst.Logger = c.Logger
|
||||
dst.MaxRetries = c.MaxRetries
|
||||
dst.RetryRule = c.RetryRule
|
||||
dst.ShouldRetry = c.ShouldRetry
|
||||
dst.DisableParamValidation = c.DisableParamValidation
|
||||
dst.DisableComputeChecksums = c.DisableComputeChecksums
|
||||
dst.S3ForcePathStyle = c.S3ForcePathStyle
|
||||
dst.DomainMode = c.DomainMode
|
||||
dst.SignerVersion = c.SignerVersion
|
||||
dst.CrcCheckEnabled = c.CrcCheckEnabled
|
||||
dst.DisableRestProtocolURICleaning = c.DisableRestProtocolURICleaning
|
||||
dst.DisableDnsCache = c.DisableDnsCache
|
||||
return dst
|
||||
}
|
||||
|
||||
// Merge merges the newcfg attribute values into this Config. Each attribute
|
||||
// will be merged into this config if the newcfg attribute's value is non-zero.
|
||||
// Due to this, newcfg attributes with zero values cannot be merged in. For
|
||||
// example bool attributes cannot be cleared using Merge, and must be explicitly
|
||||
// set on the Config structure.
|
||||
func (c Config) Merge(newcfg *Config) *Config {
|
||||
if newcfg == nil {
|
||||
return &c
|
||||
}
|
||||
|
||||
cfg := Config{}
|
||||
|
||||
if newcfg.Credentials != nil {
|
||||
cfg.Credentials = newcfg.Credentials
|
||||
} else {
|
||||
cfg.Credentials = c.Credentials
|
||||
}
|
||||
|
||||
if newcfg.Endpoint != "" {
|
||||
cfg.Endpoint = newcfg.Endpoint
|
||||
} else {
|
||||
cfg.Endpoint = c.Endpoint
|
||||
}
|
||||
|
||||
if newcfg.Ks3BillEndpoint != "" {
|
||||
cfg.Ks3BillEndpoint = newcfg.Ks3BillEndpoint
|
||||
} else {
|
||||
cfg.Ks3BillEndpoint = c.Ks3BillEndpoint
|
||||
}
|
||||
|
||||
if newcfg.Region != "" {
|
||||
cfg.Region = newcfg.Region
|
||||
} else {
|
||||
cfg.Region = c.Region
|
||||
}
|
||||
|
||||
if newcfg.DisableSSL {
|
||||
cfg.DisableSSL = newcfg.DisableSSL
|
||||
} else {
|
||||
cfg.DisableSSL = c.DisableSSL
|
||||
}
|
||||
|
||||
if newcfg.ManualSend {
|
||||
cfg.ManualSend = newcfg.ManualSend
|
||||
} else {
|
||||
cfg.ManualSend = c.ManualSend
|
||||
}
|
||||
|
||||
if newcfg.DisableDnsCache {
|
||||
cfg.DisableDnsCache = newcfg.DisableDnsCache
|
||||
} else {
|
||||
cfg.DisableDnsCache = c.DisableDnsCache
|
||||
}
|
||||
|
||||
if newcfg.HTTPClient != nil {
|
||||
cfg.HTTPClient = newcfg.HTTPClient
|
||||
} else {
|
||||
cfg.HTTPClient = c.HTTPClient
|
||||
if !cfg.DisableDnsCache {
|
||||
cfg.HTTPClient.Transport = DnsCacheTransport
|
||||
}
|
||||
}
|
||||
defaultHTTPRedirect(cfg.HTTPClient)
|
||||
|
||||
if newcfg.LogHTTPBody {
|
||||
cfg.LogHTTPBody = newcfg.LogHTTPBody
|
||||
} else {
|
||||
cfg.LogHTTPBody = c.LogHTTPBody
|
||||
}
|
||||
|
||||
if newcfg.LogLevel != 0 {
|
||||
cfg.LogLevel = newcfg.LogLevel
|
||||
} else {
|
||||
cfg.LogLevel = c.LogLevel
|
||||
}
|
||||
|
||||
if newcfg.Logger != nil {
|
||||
cfg.Logger = newcfg.Logger
|
||||
} else {
|
||||
cfg.Logger = c.Logger
|
||||
}
|
||||
|
||||
if newcfg.MaxRetries != 0 {
|
||||
cfg.MaxRetries = newcfg.MaxRetries
|
||||
} else {
|
||||
cfg.MaxRetries = c.MaxRetries
|
||||
}
|
||||
|
||||
if newcfg.RetryRule != nil {
|
||||
cfg.RetryRule = newcfg.RetryRule
|
||||
} else {
|
||||
cfg.RetryRule = c.RetryRule
|
||||
}
|
||||
|
||||
if newcfg.ShouldRetry != nil {
|
||||
cfg.ShouldRetry = newcfg.ShouldRetry
|
||||
} else {
|
||||
cfg.ShouldRetry = c.ShouldRetry
|
||||
}
|
||||
|
||||
if newcfg.DisableParamValidation {
|
||||
cfg.DisableParamValidation = newcfg.DisableParamValidation
|
||||
} else {
|
||||
cfg.DisableParamValidation = c.DisableParamValidation
|
||||
}
|
||||
|
||||
if newcfg.DisableComputeChecksums {
|
||||
cfg.DisableComputeChecksums = newcfg.DisableComputeChecksums
|
||||
} else {
|
||||
cfg.DisableComputeChecksums = c.DisableComputeChecksums
|
||||
}
|
||||
|
||||
if newcfg.S3ForcePathStyle {
|
||||
cfg.S3ForcePathStyle = newcfg.S3ForcePathStyle
|
||||
} else {
|
||||
cfg.S3ForcePathStyle = c.S3ForcePathStyle
|
||||
}
|
||||
|
||||
if newcfg.DomainMode {
|
||||
cfg.DomainMode = newcfg.DomainMode
|
||||
} else {
|
||||
cfg.DomainMode = c.DomainMode
|
||||
}
|
||||
if newcfg.SignerVersion != "" {
|
||||
cfg.SignerVersion = newcfg.SignerVersion
|
||||
} else {
|
||||
cfg.SignerVersion = c.SignerVersion
|
||||
}
|
||||
if newcfg.CrcCheckEnabled {
|
||||
cfg.CrcCheckEnabled = newcfg.CrcCheckEnabled
|
||||
} else {
|
||||
cfg.CrcCheckEnabled = c.CrcCheckEnabled
|
||||
}
|
||||
if newcfg.DisableRestProtocolURICleaning {
|
||||
cfg.DisableRestProtocolURICleaning = newcfg.DisableRestProtocolURICleaning
|
||||
} else {
|
||||
cfg.DisableRestProtocolURICleaning = c.DisableRestProtocolURICleaning
|
||||
}
|
||||
|
||||
return &cfg
|
||||
}
|
||||
|
||||
// Define the level of the output log
|
||||
const (
|
||||
Off = iota
|
||||
Error
|
||||
Warn
|
||||
Info
|
||||
Debug
|
||||
)
|
||||
|
||||
// LogTag Tag for each level of log
|
||||
var LogTag = []string{"[error]", "[warn]", "[info]", "[debug]"}
|
||||
|
||||
func (c Config) writeLog(level uint, format string, a ...interface{}) {
|
||||
if c.LogLevel < level {
|
||||
return
|
||||
}
|
||||
|
||||
var logBuffer bytes.Buffer
|
||||
logBuffer.WriteString(time.Now().Format("2006/01/02 15:04:05"))
|
||||
logBuffer.WriteString(" ")
|
||||
logBuffer.WriteString(LogTag[level-1])
|
||||
logBuffer.WriteString(fmt.Sprintf(format, a...))
|
||||
if logBuffer.Bytes()[logBuffer.Len()-1] != '\n' {
|
||||
logBuffer.WriteString("\n")
|
||||
}
|
||||
fmt.Fprintf(c.Logger, "%s", logBuffer.String())
|
||||
}
|
||||
|
||||
func (c Config) LogError(format string, a ...interface{}) {
|
||||
if c.LogLevel < Error {
|
||||
return
|
||||
}
|
||||
c.writeLog(Error, format, a...)
|
||||
}
|
||||
|
||||
func (c Config) LogWarn(format string, a ...interface{}) {
|
||||
if c.LogLevel < Warn {
|
||||
return
|
||||
}
|
||||
c.writeLog(Warn, format, a...)
|
||||
}
|
||||
|
||||
func (c Config) LogInfo(format string, a ...interface{}) {
|
||||
if c.LogLevel < Info {
|
||||
return
|
||||
}
|
||||
c.writeLog(Info, format, a...)
|
||||
}
|
||||
|
||||
func (c Config) LogDebug(format string, a ...interface{}) {
|
||||
if c.LogLevel < Debug {
|
||||
return
|
||||
}
|
||||
c.writeLog(Debug, format, a...)
|
||||
}
|
||||
22
vendor/github.com/ks3sdklib/aws-sdk-go/aws/context.go
generated
vendored
Normal file
22
vendor/github.com/ks3sdklib/aws-sdk-go/aws/context.go
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
)
|
||||
|
||||
type Context = context.Context
|
||||
|
||||
// SetContext adds a Context to the current request that can be used to cancel
|
||||
func (r *Request) SetContext(ctx Context) {
|
||||
if ctx == nil {
|
||||
r.Error = apierr.New("InvalidParameter", "context cannot be nil", nil)
|
||||
}
|
||||
r.context = ctx
|
||||
r.HTTPRequest = r.HTTPRequest.WithContext(ctx)
|
||||
}
|
||||
|
||||
// BackgroundContext returns a context that will never be canceled
|
||||
func BackgroundContext() Context {
|
||||
return context.Background()
|
||||
}
|
||||
81
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/chain_provider.go
generated
vendored
Normal file
81
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/chain_provider.go
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNoValidProvidersFoundInChain Is returned when there are no valid
|
||||
// providers in the ChainProvider.
|
||||
ErrNoValidProvidersFoundInChain = apierr.New("NoCredentialProviders", "no valid providers in chain", nil)
|
||||
)
|
||||
|
||||
// A ChainProvider will search for a provider which returns credentials
|
||||
// and cache that provider until Retrieve is called again.
|
||||
//
|
||||
// The ChainProvider provides a way of chaining multiple providers together
|
||||
// which will pick the first available using priority order of the Providers
|
||||
// in the list.
|
||||
//
|
||||
// If none of the Providers retrieve valid credentials Value, ChainProvider's
|
||||
// Retrieve() will return the error ErrNoValidProvidersFoundInChain.
|
||||
//
|
||||
// If a Provider is found which returns valid credentials Value ChainProvider
|
||||
// will cache that Provider for all calls to IsExpired(), until Retrieve is
|
||||
// called again.
|
||||
//
|
||||
// Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider.
|
||||
// In this example EnvProvider will first check if any credentials are available
|
||||
// vai the environment variables. If there are none ChainProvider will check
|
||||
// the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider
|
||||
// does not return any credentials ChainProvider will return the error
|
||||
// ErrNoValidProvidersFoundInChain
|
||||
//
|
||||
// creds := NewChainCredentials(
|
||||
// []Provider{
|
||||
// &EnvProvider{},
|
||||
// &EC2RoleProvider{},
|
||||
// })
|
||||
// creds.Retrieve()
|
||||
//
|
||||
type ChainProvider struct {
|
||||
Providers []Provider
|
||||
curr Provider
|
||||
}
|
||||
|
||||
// NewChainCredentials returns a pointer to a new Credentials object
|
||||
// wrapping a chain of providers.
|
||||
func NewChainCredentials(providers []Provider) *Credentials {
|
||||
return NewCredentials(&ChainProvider{
|
||||
Providers: append([]Provider{}, providers...),
|
||||
})
|
||||
}
|
||||
|
||||
// Retrieve returns the credentials value or error if no provider returned
|
||||
// without error.
|
||||
//
|
||||
// If a provider is found it will be cached and any calls to IsExpired()
|
||||
// will return the expired state of the cached provider.
|
||||
func (c *ChainProvider) Retrieve() (Value, error) {
|
||||
for _, p := range c.Providers {
|
||||
if creds, err := p.Retrieve(); err == nil {
|
||||
c.curr = p
|
||||
return creds, nil
|
||||
}
|
||||
}
|
||||
c.curr = nil
|
||||
|
||||
// TODO better error reporting. maybe report error for each failed retrieve?
|
||||
|
||||
return Value{}, ErrNoValidProvidersFoundInChain
|
||||
}
|
||||
|
||||
// IsExpired will returned the expired state of the currently cached provider
|
||||
// if there is one. If there is no current provider, true will be returned.
|
||||
func (c *ChainProvider) IsExpired() bool {
|
||||
if c.curr != nil {
|
||||
return c.curr.IsExpired()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
178
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/credentials.go
generated
vendored
Normal file
178
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/credentials.go
generated
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
// Package credentials provides credential retrieval and management
|
||||
//
|
||||
// The Credentials is the primary method of getting access to and managing
|
||||
// credentials Values. Using dependency injection retrieval of the credential
|
||||
// values is handled by a object which satisfies the Provider interface.
|
||||
//
|
||||
// By default the Credentials.Get() will cache the successful result of a
|
||||
// Provider's Retrieve() until Provider.IsExpired() returns true. At which
|
||||
// point Credentials will call Provider's Retrieve() to get new credential Value.
|
||||
//
|
||||
// The Provider is responsible for determining when credentials Value have expired.
|
||||
// It is also important to note that Credentials will always call Retrieve the
|
||||
// first time Credentials.Get() is called.
|
||||
//
|
||||
// Example of using the environment variable credentials.
|
||||
//
|
||||
// creds := NewEnvCredentials()
|
||||
//
|
||||
// // Retrieve the credentials value
|
||||
// credValue, err := creds.Get()
|
||||
// if err != nil {
|
||||
// // handle error
|
||||
// }
|
||||
//
|
||||
// Example of forcing credentials to expire and be refreshed on the next Get().
|
||||
// This may be helpful to proactively expire credentials and refresh them sooner
|
||||
// than they would naturally expire on their own.
|
||||
//
|
||||
// creds := NewCredentials(&EC2RoleProvider{})
|
||||
// creds.Expire()
|
||||
// credsValue, err := creds.Get()
|
||||
// // New credentials will be retrieved instead of from cache.
|
||||
//
|
||||
//
|
||||
// Custom Provider
|
||||
//
|
||||
// Each Provider built into this package also provides a helper method to generate
|
||||
// a Credentials pointer setup with the provider. To use a custom Provider just
|
||||
// create a type which satisfies the Provider interface and pass it to the
|
||||
// NewCredentials method.
|
||||
//
|
||||
// type MyProvider struct{}
|
||||
// func (m *MyProvider) Retrieve() (Value, error) {...}
|
||||
// func (m *MyProvider) IsExpired() bool {...}
|
||||
//
|
||||
// creds := NewCredentials(&MyProvider{})
|
||||
// credValue, err := creds.Get()
|
||||
//
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Create an empty Credential object that can be used as dummy placeholder
|
||||
// credentials for requests that do not need signed.
|
||||
//
|
||||
// This Credentials can be used to configure a service to not sign requests
|
||||
// when making service API calls. For example, when accessing public
|
||||
// s3 buckets.
|
||||
//
|
||||
// svc := s3.New(&aws.Config{Credentials: AnonymousCredentials})
|
||||
// // Access public S3 buckets.
|
||||
//
|
||||
var AnonymousCredentials = NewStaticCredentials("", "", "")
|
||||
|
||||
// A Value is the AWS credentials value for individual credential fields.
|
||||
type Value struct {
|
||||
// AWS Access key ID
|
||||
AccessKeyID string
|
||||
|
||||
// AWS Secret Access Key
|
||||
SecretAccessKey string
|
||||
|
||||
// AWS Session Token
|
||||
SessionToken string
|
||||
}
|
||||
|
||||
// A Provider is the interface for any component which will provide credentials
|
||||
// Value. A provider is required to manage its own Expired state, and what to
|
||||
// be expired means.
|
||||
//
|
||||
// The Provider should not need to implement its own mutexes, because
|
||||
// that will be managed by Credentials.
|
||||
type Provider interface {
|
||||
// Refresh returns nil if it successfully retrieved the value.
|
||||
// Error is returned if the value were not obtainable, or empty.
|
||||
Retrieve() (Value, error)
|
||||
|
||||
// IsExpired returns if the credentials are no longer valid, and need
|
||||
// to be retrieved.
|
||||
IsExpired() bool
|
||||
}
|
||||
|
||||
// A Credentials provides synchronous safe retrieval of AWS credentials Value.
|
||||
// Credentials will cache the credentials value until they expire. Once the value
|
||||
// expires the next Get will attempt to retrieve valid credentials.
|
||||
//
|
||||
// Credentials is safe to use across multiple goroutines and will manage the
|
||||
// synchronous state so the Providers do not need to implement their own
|
||||
// synchronization.
|
||||
//
|
||||
// The first Credentials.Get() will always call Provider.Retrieve() to get the
|
||||
// first instance of the credentials Value. All calls to Get() after that
|
||||
// will return the cached credentials Value until IsExpired() returns true.
|
||||
type Credentials struct {
|
||||
creds Value
|
||||
forceRefresh bool
|
||||
m sync.Mutex
|
||||
|
||||
provider Provider
|
||||
}
|
||||
|
||||
// NewCredentials returns a pointer to a new Credentials with the provider set.
|
||||
func NewCredentials(provider Provider) *Credentials {
|
||||
return &Credentials{
|
||||
provider: provider,
|
||||
forceRefresh: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns the credentials value, or error if the credentials Value failed
|
||||
// to be retrieved.
|
||||
//
|
||||
// Will return the cached credentials Value if it has not expired. If the
|
||||
// credentials Value has expired the Provider's Retrieve() will be called
|
||||
// to refresh the credentials.
|
||||
//
|
||||
// If Credentials.Expire() was called the credentials Value will be force
|
||||
// expired, and the next call to Get() will cause them to be refreshed.
|
||||
func (c *Credentials) Get() (Value, error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if c.isExpired() {
|
||||
creds, err := c.provider.Retrieve()
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
c.creds = creds
|
||||
c.forceRefresh = false
|
||||
}
|
||||
|
||||
return c.creds, nil
|
||||
}
|
||||
|
||||
// Expire expires the credentials and forces them to be retrieved on the
|
||||
// next call to Get().
|
||||
//
|
||||
// This will override the Provider's expired state, and force Credentials
|
||||
// to call the Provider's Retrieve().
|
||||
func (c *Credentials) Expire() {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
c.forceRefresh = true
|
||||
}
|
||||
|
||||
// IsExpired returns if the credentials are no longer valid, and need
|
||||
// to be retrieved.
|
||||
//
|
||||
// If the Credentials were forced to be expired with Expire() this will
|
||||
// reflect that override.
|
||||
func (c *Credentials) IsExpired() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
return c.isExpired()
|
||||
}
|
||||
|
||||
// isExpired helper method wrapping the definition of expired credentials.
|
||||
func (c *Credentials) isExpired() bool {
|
||||
return c.forceRefresh || c.provider.IsExpired()
|
||||
}
|
||||
|
||||
// Provide a stub-able time.Now for unit tests so expiry can be tested.
|
||||
var currentTime = time.Now
|
||||
173
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/ec2_role_provider.go
generated
vendored
Normal file
173
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/ec2_role_provider.go
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
)
|
||||
|
||||
const metadataCredentialsEndpoint = "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
|
||||
|
||||
// A EC2RoleProvider retrieves credentials from the EC2 service, and keeps track if
|
||||
// those credentials are expired.
|
||||
//
|
||||
// Example how to configure the EC2RoleProvider with custom http Client, Endpoint
|
||||
// or ExpiryWindow
|
||||
//
|
||||
// p := &credentials.EC2RoleProvider{
|
||||
// // Pass in a custom timeout to be used when requesting
|
||||
// // IAM EC2 Role credentials.
|
||||
// Client: &http.Client{
|
||||
// Timeout: 10 * time.Second,
|
||||
// },
|
||||
// // Use default EC2 Role metadata endpoint, Alternate endpoints can be
|
||||
// // specified setting Endpoint to something else.
|
||||
// Endpoint: "",
|
||||
// // Do not use early expiry of credentials. If a non zero value is
|
||||
// // specified the credentials will be expired early
|
||||
// ExpiryWindow: 0,
|
||||
// }
|
||||
//
|
||||
type EC2RoleProvider struct {
|
||||
// Endpoint must be fully quantified URL
|
||||
Endpoint string
|
||||
|
||||
// HTTP client to use when connecting to EC2 service
|
||||
Client *http.Client
|
||||
|
||||
// ExpiryWindow will allow the credentials to trigger refreshing prior to
|
||||
// the credentials actually expiring. This is beneficial so race conditions
|
||||
// with expiring credentials do not cause request to fail unexpectedly
|
||||
// due to ExpiredTokenException exceptions.
|
||||
//
|
||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
||||
// 10 seconds before the credentials are actually expired.
|
||||
//
|
||||
// If ExpiryWindow is 0 or less it will be ignored.
|
||||
ExpiryWindow time.Duration
|
||||
|
||||
// The date/time at which the credentials expire.
|
||||
expiresOn time.Time
|
||||
}
|
||||
|
||||
// NewEC2RoleCredentials returns a pointer to a new Credentials object
|
||||
// wrapping the EC2RoleProvider.
|
||||
//
|
||||
// Takes a custom http.Client which can be configured for custom handling of
|
||||
// things such as timeout.
|
||||
//
|
||||
// Endpoint is the URL that the EC2RoleProvider will connect to when retrieving
|
||||
// role and credentials.
|
||||
//
|
||||
// Window is the expiry window that will be subtracted from the expiry returned
|
||||
// by the role credential request. This is done so that the credentials will
|
||||
// expire sooner than their actual lifespan.
|
||||
func NewEC2RoleCredentials(client *http.Client, endpoint string, window time.Duration) *Credentials {
|
||||
return NewCredentials(&EC2RoleProvider{
|
||||
Endpoint: endpoint,
|
||||
Client: client,
|
||||
ExpiryWindow: window,
|
||||
})
|
||||
}
|
||||
|
||||
// Retrieve retrieves credentials from the EC2 service.
|
||||
// Error will be returned if the request fails, or unable to extract
|
||||
// the desired credentials.
|
||||
func (m *EC2RoleProvider) Retrieve() (Value, error) {
|
||||
if m.Client == nil {
|
||||
m.Client = http.DefaultClient
|
||||
}
|
||||
if m.Endpoint == "" {
|
||||
m.Endpoint = metadataCredentialsEndpoint
|
||||
}
|
||||
|
||||
credsList, err := requestCredList(m.Client, m.Endpoint)
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
|
||||
if len(credsList) == 0 {
|
||||
return Value{}, apierr.New("EmptyEC2RoleList", "empty EC2 Role list", nil)
|
||||
}
|
||||
credsName := credsList[0]
|
||||
|
||||
roleCreds, err := requestCred(m.Client, m.Endpoint, credsName)
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
|
||||
m.expiresOn = roleCreds.Expiration
|
||||
if m.ExpiryWindow > 0 {
|
||||
// Offset based on expiry window if set.
|
||||
m.expiresOn = m.expiresOn.Add(-m.ExpiryWindow)
|
||||
}
|
||||
|
||||
return Value{
|
||||
AccessKeyID: roleCreds.AccessKeyID,
|
||||
SecretAccessKey: roleCreds.SecretAccessKey,
|
||||
SessionToken: roleCreds.Token,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// IsExpired returns if the credentials are expired.
|
||||
func (m *EC2RoleProvider) IsExpired() bool {
|
||||
return m.expiresOn.Before(currentTime())
|
||||
}
|
||||
|
||||
// A ec2RoleCredRespBody provides the shape for deserializing credential
|
||||
// request responses.
|
||||
type ec2RoleCredRespBody struct {
|
||||
Expiration time.Time
|
||||
AccessKeyID string
|
||||
SecretAccessKey string
|
||||
Token string
|
||||
}
|
||||
|
||||
// requestCredList requests a list of credentials from the EC2 service.
|
||||
// If there are no credentials, or there is an error making or receiving the request
|
||||
func requestCredList(client *http.Client, endpoint string) ([]string, error) {
|
||||
resp, err := client.Get(endpoint)
|
||||
if err != nil {
|
||||
return nil, apierr.New("ListEC2Role", "failed to list EC2 Roles", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
credsList := []string{}
|
||||
s := bufio.NewScanner(resp.Body)
|
||||
for s.Scan() {
|
||||
credsList = append(credsList, s.Text())
|
||||
}
|
||||
|
||||
if err := s.Err(); err != nil {
|
||||
return nil, apierr.New("ReadEC2Role", "failed to read list of EC2 Roles", err)
|
||||
}
|
||||
|
||||
return credsList, nil
|
||||
}
|
||||
|
||||
// requestCred requests the credentials for a specific credentials from the EC2 service.
|
||||
//
|
||||
// If the credentials cannot be found, or there is an error reading the response
|
||||
// and error will be returned.
|
||||
func requestCred(client *http.Client, endpoint, credsName string) (*ec2RoleCredRespBody, error) {
|
||||
resp, err := client.Get(endpoint + credsName)
|
||||
if err != nil {
|
||||
return nil, apierr.New("GetEC2RoleCredentials",
|
||||
fmt.Sprintf("failed to get %s EC2 Role credentials", credsName),
|
||||
err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
respCreds := &ec2RoleCredRespBody{}
|
||||
if err := json.NewDecoder(resp.Body).Decode(respCreds); err != nil {
|
||||
return nil, apierr.New("DecodeEC2RoleCredentials",
|
||||
fmt.Sprintf("failed to decode %s EC2 Role credentials", credsName),
|
||||
err)
|
||||
}
|
||||
|
||||
return respCreds, nil
|
||||
}
|
||||
67
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/env_provider.go
generated
vendored
Normal file
67
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/env_provider.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrAccessKeyIDNotFound is returned when the AWS Access Key ID can't be
|
||||
// found in the process's environment.
|
||||
ErrAccessKeyIDNotFound = apierr.New("EnvAccessKeyNotFound", "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment", nil)
|
||||
// ErrSecretAccessKeyNotFound is returned when the AWS Secret Access Key
|
||||
// can't be found in the process's environment.
|
||||
ErrSecretAccessKeyNotFound = apierr.New("EnvSecretNotFound", "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment", nil)
|
||||
)
|
||||
|
||||
// A EnvProvider retrieves credentials from the environment variables of the
|
||||
// running process. Environment credentials never expire.
|
||||
//
|
||||
// Environment variables used:
|
||||
// - Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY
|
||||
// - Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY
|
||||
type EnvProvider struct {
|
||||
retrieved bool
|
||||
}
|
||||
|
||||
// NewEnvCredentials returns a pointer to a new Credentials object
|
||||
// wrapping the environment variable provider.
|
||||
func NewEnvCredentials() *Credentials {
|
||||
return NewCredentials(&EnvProvider{})
|
||||
}
|
||||
|
||||
// Retrieve retrieves the keys from the environment.
|
||||
func (e *EnvProvider) Retrieve() (Value, error) {
|
||||
e.retrieved = false
|
||||
|
||||
id := os.Getenv("AWS_ACCESS_KEY_ID")
|
||||
if id == "" {
|
||||
id = os.Getenv("AWS_ACCESS_KEY")
|
||||
}
|
||||
|
||||
secret := os.Getenv("AWS_SECRET_ACCESS_KEY")
|
||||
if secret == "" {
|
||||
secret = os.Getenv("AWS_SECRET_KEY")
|
||||
}
|
||||
|
||||
if id == "" {
|
||||
return Value{}, ErrAccessKeyIDNotFound
|
||||
}
|
||||
|
||||
if secret == "" {
|
||||
return Value{}, ErrSecretAccessKeyNotFound
|
||||
}
|
||||
|
||||
e.retrieved = true
|
||||
return Value{
|
||||
AccessKeyID: id,
|
||||
SecretAccessKey: secret,
|
||||
SessionToken: os.Getenv("AWS_SESSION_TOKEN"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// IsExpired returns if the credentials have been retrieved.
|
||||
func (e *EnvProvider) IsExpired() bool {
|
||||
return !e.retrieved
|
||||
}
|
||||
8
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/example.ini
generated
vendored
Normal file
8
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/example.ini
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
[default]
|
||||
aws_access_key_id = accessKey
|
||||
aws_secret_access_key = secret
|
||||
aws_session_token = token
|
||||
|
||||
[no_token]
|
||||
aws_access_key_id = accessKey
|
||||
aws_secret_access_key = secret
|
||||
123
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/ini.go
generated
vendored
Normal file
123
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/ini.go
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
// Package ini provides functions for parsing INI configuration files.
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
sectionRegex = regexp.MustCompile(`^\[(.*)\]$`)
|
||||
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
|
||||
)
|
||||
|
||||
// ErrSyntax is returned when there is a syntax error in an INI file.
|
||||
type ErrSyntax struct {
|
||||
Line int
|
||||
Source string // The contents of the erroneous line, without leading or trailing whitespace
|
||||
}
|
||||
|
||||
func (e ErrSyntax) Error() string {
|
||||
return fmt.Sprintf("invalid INI syntax on line %d: %s", e.Line, e.Source)
|
||||
}
|
||||
|
||||
// A File represents a parsed INI file.
|
||||
type File map[string]Section
|
||||
|
||||
// A Section represents a single section of an INI file.
|
||||
type Section map[string]string
|
||||
|
||||
// Returns a named Section. A Section will be created if one does not already exist for the given name.
|
||||
func (f File) Section(name string) Section {
|
||||
section := f[name]
|
||||
if section == nil {
|
||||
section = make(Section)
|
||||
f[name] = section
|
||||
}
|
||||
return section
|
||||
}
|
||||
|
||||
// Looks up a value for a key in a section and returns that value, along with a boolean result similar to a map lookup.
|
||||
func (f File) Get(section, key string) (value string, ok bool) {
|
||||
if s := f[section]; s != nil {
|
||||
value, ok = s[key]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Loads INI data from a reader and stores the data in the File.
|
||||
func (f File) Load(in io.Reader) (err error) {
|
||||
bufin, ok := in.(*bufio.Reader)
|
||||
if !ok {
|
||||
bufin = bufio.NewReader(in)
|
||||
}
|
||||
return parseFile(bufin, f)
|
||||
}
|
||||
|
||||
// Loads INI data from a named file and stores the data in the File.
|
||||
func (f File) LoadFile(file string) (err error) {
|
||||
in, err := os.Open(file)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer in.Close()
|
||||
return f.Load(in)
|
||||
}
|
||||
|
||||
func parseFile(in *bufio.Reader, file File) (err error) {
|
||||
section := ""
|
||||
lineNum := 0
|
||||
for done := false; !done; {
|
||||
var line string
|
||||
if line, err = in.ReadString('\n'); err != nil {
|
||||
if err == io.EOF {
|
||||
done = true
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
lineNum++
|
||||
line = strings.TrimSpace(line)
|
||||
if len(line) == 0 {
|
||||
// Skip blank lines
|
||||
continue
|
||||
}
|
||||
if line[0] == ';' || line[0] == '#' {
|
||||
// Skip comments
|
||||
continue
|
||||
}
|
||||
|
||||
if groups := assignRegex.FindStringSubmatch(line); groups != nil {
|
||||
key, val := groups[1], groups[2]
|
||||
key, val = strings.TrimSpace(key), strings.TrimSpace(val)
|
||||
file.Section(section)[key] = val
|
||||
} else if groups := sectionRegex.FindStringSubmatch(line); groups != nil {
|
||||
name := strings.TrimSpace(groups[1])
|
||||
section = name
|
||||
// Create the section if it does not exist
|
||||
file.Section(section)
|
||||
} else {
|
||||
return ErrSyntax{lineNum, line}
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Loads and returns a File from a reader.
|
||||
func Load(in io.Reader) (File, error) {
|
||||
file := make(File)
|
||||
err := file.Load(in)
|
||||
return file, err
|
||||
}
|
||||
|
||||
// Loads and returns an INI File from a file on disk.
|
||||
func LoadFile(filename string) (File, error) {
|
||||
file := make(File)
|
||||
err := file.LoadFile(filename)
|
||||
return file, err
|
||||
}
|
||||
131
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
Normal file
131
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found.
|
||||
ErrSharedCredentialsHomeNotFound = apierr.New("UserHomeNotFound", "user home directory not found.", nil)
|
||||
)
|
||||
|
||||
// A SharedCredentialsProvider retrieves credentials from the current user's home
|
||||
// directory, and keeps track if those credentials are expired.
|
||||
//
|
||||
// Profile ini file example: $HOME/.aws/credentials
|
||||
type SharedCredentialsProvider struct {
|
||||
// Path to the shared credentials file. If empty will default to current user's
|
||||
// home directory.
|
||||
Filename string
|
||||
|
||||
// AWS Profile to extract credentials from the shared credentials file. If empty
|
||||
// will default to environment variable "AWS_PROFILE" or "default" if
|
||||
// environment variable is also not set.
|
||||
Profile string
|
||||
|
||||
// retrieved states if the credentials have been successfully retrieved.
|
||||
retrieved bool
|
||||
}
|
||||
|
||||
// NewSharedCredentials returns a pointer to a new Credentials object
|
||||
// wrapping the Profile file provider.
|
||||
func NewSharedCredentials(filename, profile string) *Credentials {
|
||||
return NewCredentials(&SharedCredentialsProvider{
|
||||
Filename: filename,
|
||||
Profile: profile,
|
||||
})
|
||||
}
|
||||
|
||||
// Retrieve reads and extracts the shared credentials from the current
|
||||
// users home directory.
|
||||
func (p *SharedCredentialsProvider) Retrieve() (Value, error) {
|
||||
p.retrieved = false
|
||||
|
||||
filename, err := p.filename()
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
|
||||
creds, err := loadProfile(filename, p.profile())
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
|
||||
p.retrieved = true
|
||||
return creds, nil
|
||||
}
|
||||
|
||||
// IsExpired returns if the shared credentials have expired.
|
||||
func (p *SharedCredentialsProvider) IsExpired() bool {
|
||||
return !p.retrieved
|
||||
}
|
||||
|
||||
// loadProfiles loads from the file pointed to by shared credentials filename for profile.
|
||||
// The credentials retrieved from the profile will be returned or error. Error will be
|
||||
// returned if it fails to read from the file, or the data is invalid.
|
||||
func loadProfile(filename, profile string) (Value, error) {
|
||||
config, err := LoadFile(filename)
|
||||
if err != nil {
|
||||
return Value{}, apierr.New("SharedCredsLoad", "failed to load shared credentials file", err)
|
||||
}
|
||||
iniProfile := config.Section(profile)
|
||||
|
||||
id, ok := iniProfile["aws_access_key_id"]
|
||||
if !ok {
|
||||
return Value{}, apierr.New("SharedCredsAccessKey",
|
||||
fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename),
|
||||
nil)
|
||||
}
|
||||
|
||||
secret, ok := iniProfile["aws_secret_access_key"]
|
||||
if !ok {
|
||||
return Value{}, apierr.New("SharedCredsSecret",
|
||||
fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename),
|
||||
nil)
|
||||
}
|
||||
|
||||
token := iniProfile["aws_session_token"]
|
||||
|
||||
return Value{
|
||||
AccessKeyID: id,
|
||||
SecretAccessKey: secret,
|
||||
SessionToken: token,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// filename returns the filename to use to read AWS shared credentials.
|
||||
//
|
||||
// Will return an error if the user's home directory path cannot be found.
|
||||
func (p *SharedCredentialsProvider) filename() (string, error) {
|
||||
if p.Filename == "" {
|
||||
homeDir := os.Getenv("HOME") // *nix
|
||||
if homeDir == "" { // Windows
|
||||
homeDir = os.Getenv("USERPROFILE")
|
||||
}
|
||||
if homeDir == "" {
|
||||
return "", ErrSharedCredentialsHomeNotFound
|
||||
}
|
||||
|
||||
p.Filename = filepath.Join(homeDir, ".aws", "credentials")
|
||||
}
|
||||
|
||||
return p.Filename, nil
|
||||
}
|
||||
|
||||
// profile returns the AWS shared credentials profile. If empty will read
|
||||
// environment variable "AWS_PROFILE". If that is not set profile will
|
||||
// return "default".
|
||||
func (p *SharedCredentialsProvider) profile() string {
|
||||
if p.Profile == "" {
|
||||
p.Profile = os.Getenv("AWS_PROFILE")
|
||||
}
|
||||
if p.Profile == "" {
|
||||
p.Profile = "default"
|
||||
}
|
||||
|
||||
return p.Profile
|
||||
}
|
||||
42
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/static_provider.go
generated
vendored
Normal file
42
vendor/github.com/ks3sdklib/aws-sdk-go/aws/credentials/static_provider.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrStaticCredentialsEmpty is emitted when static credentials are empty.
|
||||
ErrStaticCredentialsEmpty = apierr.New("EmptyStaticCreds", "static credentials are empty", nil)
|
||||
)
|
||||
|
||||
// A StaticProvider is a set of credentials which are set pragmatically,
|
||||
// and will never expire.
|
||||
type StaticProvider struct {
|
||||
Value
|
||||
}
|
||||
|
||||
// NewStaticCredentials returns a pointer to a new Credentials object
|
||||
// wrapping a static credentials value provider.
|
||||
func NewStaticCredentials(id, secret, token string) *Credentials {
|
||||
return NewCredentials(&StaticProvider{Value: Value{
|
||||
AccessKeyID: id,
|
||||
SecretAccessKey: secret,
|
||||
SessionToken: token,
|
||||
}})
|
||||
}
|
||||
|
||||
// Retrieve returns the credentials or error if the credentials are invalid.
|
||||
func (s *StaticProvider) Retrieve() (Value, error) {
|
||||
if s.AccessKeyID == "" || s.SecretAccessKey == "" {
|
||||
return Value{}, ErrStaticCredentialsEmpty
|
||||
}
|
||||
|
||||
return s.Value, nil
|
||||
}
|
||||
|
||||
// IsExpired returns if the credentials are expired.
|
||||
//
|
||||
// For StaticProvider, the credentials never expired.
|
||||
func (s *StaticProvider) IsExpired() bool {
|
||||
return false
|
||||
}
|
||||
22
vendor/github.com/ks3sdklib/aws-sdk-go/aws/default_redirect.go
generated
vendored
Normal file
22
vendor/github.com/ks3sdklib/aws-sdk-go/aws/default_redirect.go
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func defaultHTTPRedirect(client *http.Client) {
|
||||
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||
if len(via) >= 10 {
|
||||
return errors.New("stopped after 10 redirects")
|
||||
}
|
||||
|
||||
// use prev Authorization if request has no Authorization
|
||||
if req.Header.Get("Authorization") == "" {
|
||||
prevAuth := via[len(via)-1].Header.Get("Authorization")
|
||||
req.Header.Set("Authorization", prevAuth)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
155
vendor/github.com/ks3sdklib/aws-sdk-go/aws/dns_resolver.go
generated
vendored
Normal file
155
vendor/github.com/ks3sdklib/aws-sdk-go/aws/dns_resolver.go
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var DnsCacheTransport = &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: DnsCacheTransportDialContext(&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}, NewDnsResolver(100)),
|
||||
ForceAttemptHTTP2: true,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
}
|
||||
|
||||
func DnsCacheTransportDialContext(dialer *net.Dialer, resolver *DnsResolver) func(context.Context, string, string) (net.Conn, error) {
|
||||
return func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
conn, err := dialer.DialContext(ctx, network, address)
|
||||
if err != nil {
|
||||
remoteAddr, exists := resolver.cache.Get(address)
|
||||
if exists {
|
||||
return dialer.DialContext(ctx, network, remoteAddr)
|
||||
}
|
||||
return conn, err
|
||||
}
|
||||
|
||||
if conn.RemoteAddr().String() != "" {
|
||||
resolver.cache.Set(address, conn.RemoteAddr().String())
|
||||
}
|
||||
|
||||
return conn, err
|
||||
}
|
||||
}
|
||||
|
||||
type DnsResolver struct {
|
||||
cache *FIFOCache
|
||||
}
|
||||
|
||||
// NewDnsResolver 创建一个新的 DNS 解析器,使用固定长度的 FIFO 缓存
|
||||
func NewDnsResolver(maxSize int) *DnsResolver {
|
||||
return &DnsResolver{
|
||||
cache: NewFIFOCache(maxSize),
|
||||
}
|
||||
}
|
||||
|
||||
// FIFOCache 实现一个固定大小的并发安全FIFO(先进先出)缓存
|
||||
// 当缓存满时,添加新条目会自动淘汰最早插入的条目
|
||||
type FIFOCache struct {
|
||||
maxSize int // 缓存的最大容量
|
||||
cache map[string]string // 存储键值对的映射
|
||||
keys *list.List // 使用链表维护键的插入顺序(FIFO)
|
||||
rwMutex sync.RWMutex // 读写锁,保证并发安全
|
||||
}
|
||||
|
||||
// NewFIFOCache 创建并返回一个新的FIFOCache实例
|
||||
// 参数:
|
||||
//
|
||||
// maxSize: 缓存的最大容量,必须大于0,否则默认为100
|
||||
//
|
||||
// 返回值:
|
||||
//
|
||||
// *FIFOCache: 新创建的缓存实例
|
||||
func NewFIFOCache(maxSize int) *FIFOCache {
|
||||
if maxSize < 1 {
|
||||
maxSize = 100
|
||||
}
|
||||
return &FIFOCache{
|
||||
maxSize: maxSize,
|
||||
cache: make(map[string]string),
|
||||
keys: list.New(),
|
||||
}
|
||||
}
|
||||
|
||||
// Set 添加或更新一个键值对到缓存中
|
||||
// 如果缓存已满且键不存在,会淘汰最早插入的条目
|
||||
// 参数:
|
||||
//
|
||||
// key: 要添加或更新的键
|
||||
// value: 要添加或更新的值
|
||||
//
|
||||
// 返回值:
|
||||
//
|
||||
// string: 如果键已存在,返回被替换的旧值;否则返回空字符串
|
||||
// bool: 表示是否替换了现有值(true表示替换,false表示新增)
|
||||
func (c *FIFOCache) Set(key, value string) (string, bool) {
|
||||
c.rwMutex.Lock()
|
||||
defer c.rwMutex.Unlock()
|
||||
|
||||
// 检查键是否已存在
|
||||
oldValue, exists := c.cache[key]
|
||||
if exists {
|
||||
// 更新现有键的值
|
||||
c.cache[key] = value
|
||||
return oldValue, true
|
||||
}
|
||||
|
||||
// 缓存已满,淘汰最旧的条目
|
||||
if c.keys.Len() >= c.maxSize {
|
||||
oldest := c.keys.Front()
|
||||
if oldest != nil {
|
||||
oldestKey := oldest.Value.(string)
|
||||
delete(c.cache, oldestKey)
|
||||
c.keys.Remove(oldest)
|
||||
}
|
||||
}
|
||||
|
||||
// 添加新条目
|
||||
c.cache[key] = value
|
||||
c.keys.PushBack(key)
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Get 从缓存中获取指定键对应的值
|
||||
// 参数:
|
||||
//
|
||||
// key: 要查找的键
|
||||
//
|
||||
// 返回值:
|
||||
//
|
||||
// string: 找到的值(如果键不存在则返回空字符串)
|
||||
// bool: 表示键是否存在(true表示存在,false表示不存在)
|
||||
func (c *FIFOCache) Get(key string) (string, bool) {
|
||||
c.rwMutex.RLock()
|
||||
defer c.rwMutex.RUnlock()
|
||||
|
||||
value, exists := c.cache[key]
|
||||
return value, exists
|
||||
}
|
||||
|
||||
// Size 返回缓存中当前存储的条目数量
|
||||
// 返回值:
|
||||
//
|
||||
// int: 当前缓存中的条目数量
|
||||
func (c *FIFOCache) Size() int {
|
||||
c.rwMutex.RLock()
|
||||
defer c.rwMutex.RUnlock()
|
||||
return len(c.cache)
|
||||
}
|
||||
|
||||
// GetMaxSize 返回缓存的最大容量
|
||||
// 返回值:
|
||||
//
|
||||
// int: 缓存的最大容量
|
||||
func (c *FIFOCache) GetMaxSize() int {
|
||||
return c.maxSize
|
||||
}
|
||||
161
vendor/github.com/ks3sdklib/aws-sdk-go/aws/handler_functions.go
generated
vendored
Normal file
161
vendor/github.com/ks3sdklib/aws-sdk-go/aws/handler_functions.go
generated
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/retry"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/awserr"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
)
|
||||
|
||||
var sleepDelay = func(delay time.Duration) {
|
||||
time.Sleep(delay)
|
||||
}
|
||||
|
||||
// Interface for matching types which also have a Len method.
|
||||
type lener interface {
|
||||
Len() int
|
||||
}
|
||||
|
||||
// BuildContentLength builds the content length of a request based on the body,
|
||||
// or will use the HTTPRequest.Header's "Content-Length" if defined. If unable
|
||||
// to determine request body length and no "Content-Length" was specified it will panic.
|
||||
func BuildContentLength(r *Request) {
|
||||
if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" {
|
||||
length, _ := strconv.ParseInt(slength, 10, 64)
|
||||
r.HTTPRequest.ContentLength = length
|
||||
return
|
||||
}
|
||||
|
||||
var length int64
|
||||
switch body := r.Body.(type) {
|
||||
case nil:
|
||||
length = 0
|
||||
case lener:
|
||||
length = int64(body.Len())
|
||||
case io.Seeker:
|
||||
r.bodyStart, _ = body.Seek(0, 1)
|
||||
end, _ := body.Seek(0, 2)
|
||||
body.Seek(r.bodyStart, 0) // make sure to seek back to original location
|
||||
length = end - r.bodyStart
|
||||
default:
|
||||
panic("Cannot get length of body, must provide `ContentLength`")
|
||||
}
|
||||
|
||||
r.HTTPRequest.ContentLength = length
|
||||
r.HTTPRequest.Header.Set("Content-Length", fmt.Sprintf("%d", length))
|
||||
}
|
||||
|
||||
// UserAgentHandler is a request handler for injecting User agent into requests.
|
||||
func UserAgentHandler(r *Request) {
|
||||
r.HTTPRequest.Header.Set("User-Agent", SDKName+"/"+SDKVersion)
|
||||
}
|
||||
func ContentTypeHandler(r *Request) {
|
||||
if len(r.HTTPRequest.Header["Content-Type"]) == 0 {
|
||||
r.HTTPRequest.Header.Set("Content-Type", "application/xml")
|
||||
}
|
||||
}
|
||||
|
||||
var reStatusCode = regexp.MustCompile(`^(\d+)`)
|
||||
|
||||
// SendHandler is a request handler to send service request using HTTP client.
|
||||
func SendHandler(r *Request) {
|
||||
|
||||
var err error
|
||||
if r.HTTPRequest.ContentLength <= 0 {
|
||||
r.HTTPRequest.Body = http.NoBody
|
||||
}
|
||||
r.HTTPResponse, err = r.Service.Config.HTTPClient.Do(r.HTTPRequest)
|
||||
if err != nil {
|
||||
// Capture the case where url.Error is returned for error processing
|
||||
// response. e.g. 301 without location header comes back as string
|
||||
// error and r.HTTPResponse is nil. Other url redirect errors will
|
||||
// comeback in a similar method.
|
||||
if e, ok := err.(*url.Error); ok {
|
||||
if s := reStatusCode.FindStringSubmatch(e.Error()); s != nil {
|
||||
code, _ := strconv.ParseInt(s[1], 10, 64)
|
||||
r.HTTPResponse = &http.Response{
|
||||
StatusCode: int(code),
|
||||
Status: http.StatusText(int(code)),
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
// Catch all other request errors.
|
||||
r.Error = apierr.New("RequestError", "send request failed", err)
|
||||
r.Retryable.Set(true) // network errors are retryable
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateResponseHandler is a request handler to validate service response.
|
||||
func ValidateResponseHandler(r *Request) {
|
||||
if r.HTTPResponse.StatusCode == 0 || r.HTTPResponse.StatusCode >= 300 {
|
||||
// this may be replaced by an UnmarshalError handler
|
||||
r.Error = apierr.New("UnknownError", "unknown error", nil)
|
||||
}
|
||||
}
|
||||
|
||||
// AfterRetryHandler performs final checks to determine if the request should
|
||||
// be retried and how long to delay.
|
||||
func AfterRetryHandler(r *Request) {
|
||||
// If one of the other handlers already set the retry state
|
||||
// we don't want to override it based on the service's state
|
||||
if !r.Retryable.IsSet() {
|
||||
r.Retryable.Set(r.Service.ShouldRetry(r.Error))
|
||||
}
|
||||
|
||||
if r.WillRetry() {
|
||||
r.RetryCount++
|
||||
delay := r.Service.RetryRule.GetDelay(int(r.RetryCount))
|
||||
if delay < 0 {
|
||||
delay = 0
|
||||
}
|
||||
r.RetryDelay = delay
|
||||
|
||||
r.Config.LogWarn("Tried %d times, will retry in %d ms.", r.RetryCount, r.RetryDelay.Milliseconds())
|
||||
sleepDelay(r.RetryDelay)
|
||||
|
||||
// when the expired token exception occurs the credentials
|
||||
// need to be expired locally so that the next request to
|
||||
// get credentials will trigger a credentials refresh.
|
||||
if r.Error != nil {
|
||||
if err, ok := r.Error.(awserr.Error); ok {
|
||||
if retry.IsCodeExpiredCreds(err.Code()) {
|
||||
r.Config.Credentials.Expire()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r.Error = nil
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrMissingRegion is an error that is returned if region configuration is
|
||||
// not found.
|
||||
ErrMissingRegion error = apierr.New("MissingRegion", "could not find region configuration", nil)
|
||||
|
||||
// ErrMissingEndpoint is an error that is returned if an endpoint cannot be
|
||||
// resolved for a service.
|
||||
ErrMissingEndpoint error = apierr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil)
|
||||
)
|
||||
|
||||
// ValidateEndpointHandler is a request handler to validate a request had the
|
||||
// appropriate Region and Endpoint set. Will set r.Error if the endpoint or
|
||||
// region is not valid.
|
||||
func ValidateEndpointHandler(r *Request) {
|
||||
if r.Service.SigningRegion == "" && r.Service.Config.Region == "" {
|
||||
r.Error = ErrMissingRegion
|
||||
} else if r.Service.Endpoint == "" {
|
||||
r.Error = ErrMissingEndpoint
|
||||
}
|
||||
}
|
||||
88
vendor/github.com/ks3sdklib/aws-sdk-go/aws/handlers.go
generated
vendored
Normal file
88
vendor/github.com/ks3sdklib/aws-sdk-go/aws/handlers.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
package aws
|
||||
|
||||
// A Handlers provides a collection of request handlers for various
|
||||
// stages of handling requests.
|
||||
type Handlers struct {
|
||||
Validate HandlerList
|
||||
Build HandlerList
|
||||
Sign HandlerList
|
||||
Send HandlerList
|
||||
ValidateResponse HandlerList
|
||||
Unmarshal HandlerList
|
||||
UnmarshalMeta HandlerList
|
||||
UnmarshalError HandlerList
|
||||
Retry HandlerList
|
||||
AfterRetry HandlerList
|
||||
CheckCrc64 HandlerList
|
||||
}
|
||||
|
||||
// copy returns of this handler's lists.
|
||||
func (h *Handlers) copy() Handlers {
|
||||
return Handlers{
|
||||
Validate: h.Validate.copy(),
|
||||
Build: h.Build.copy(),
|
||||
Sign: h.Sign.copy(),
|
||||
Send: h.Send.copy(),
|
||||
ValidateResponse: h.ValidateResponse.copy(),
|
||||
Unmarshal: h.Unmarshal.copy(),
|
||||
UnmarshalError: h.UnmarshalError.copy(),
|
||||
UnmarshalMeta: h.UnmarshalMeta.copy(),
|
||||
Retry: h.Retry.copy(),
|
||||
AfterRetry: h.AfterRetry.copy(),
|
||||
CheckCrc64: h.CheckCrc64.copy(),
|
||||
}
|
||||
}
|
||||
|
||||
// Clear removes callback functions for all handlers
|
||||
func (h *Handlers) Clear() {
|
||||
h.Validate.Clear()
|
||||
h.Build.Clear()
|
||||
h.Send.Clear()
|
||||
h.Sign.Clear()
|
||||
h.Unmarshal.Clear()
|
||||
h.UnmarshalMeta.Clear()
|
||||
h.UnmarshalError.Clear()
|
||||
h.ValidateResponse.Clear()
|
||||
h.Retry.Clear()
|
||||
h.AfterRetry.Clear()
|
||||
h.CheckCrc64.Clear()
|
||||
}
|
||||
|
||||
// A HandlerList manages zero or more handlers in a list.
|
||||
type HandlerList struct {
|
||||
list []func(*Request)
|
||||
}
|
||||
|
||||
// copy creates a copy of the handler list.
|
||||
func (l *HandlerList) copy() HandlerList {
|
||||
var n HandlerList
|
||||
n.list = append([]func(*Request){}, l.list...)
|
||||
return n
|
||||
}
|
||||
|
||||
// Clear clears the handler list.
|
||||
func (l *HandlerList) Clear() {
|
||||
l.list = []func(*Request){}
|
||||
}
|
||||
|
||||
// Len returns the number of handlers in the list.
|
||||
func (l *HandlerList) Len() int {
|
||||
return len(l.list)
|
||||
}
|
||||
|
||||
// PushBack pushes handlers f to the back of the handler list.
|
||||
func (l *HandlerList) PushBack(f ...func(*Request)) {
|
||||
l.list = append(l.list, f...)
|
||||
}
|
||||
|
||||
// PushFront pushes handlers f to the front of the handler list.
|
||||
func (l *HandlerList) PushFront(f ...func(*Request)) {
|
||||
l.list = append(f, l.list...)
|
||||
}
|
||||
|
||||
// Run executes all handlers in the list with a given request object.
|
||||
func (l *HandlerList) Run(r *Request) {
|
||||
for _, f := range l.list {
|
||||
f(r)
|
||||
}
|
||||
}
|
||||
102
vendor/github.com/ks3sdklib/aws-sdk-go/aws/param_validator.go
generated
vendored
Normal file
102
vendor/github.com/ks3sdklib/aws-sdk-go/aws/param_validator.go
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
)
|
||||
|
||||
// ValidateParameters is a request handler to validate the input parameters.
|
||||
// Validating parameters only has meaning if done prior to the request being sent.
|
||||
func ValidateParameters(r *Request) {
|
||||
if r.ParamsFilled() {
|
||||
v := validator{errors: []string{}}
|
||||
v.validateAny(reflect.ValueOf(r.Params), "")
|
||||
|
||||
if count := len(v.errors); count > 0 {
|
||||
format := "%d validation errors:\n- %s"
|
||||
msg := fmt.Sprintf(format, count, strings.Join(v.errors, "\n- "))
|
||||
r.Error = apierr.New("InvalidParameter", msg, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A validator validates values. Collects validations errors which occurs.
|
||||
type validator struct {
|
||||
errors []string
|
||||
}
|
||||
|
||||
// validateAny will validate any struct, slice or map type. All validations
|
||||
// are also performed recursively for nested types.
|
||||
func (v *validator) validateAny(value reflect.Value, path string) {
|
||||
value = reflect.Indirect(value)
|
||||
if !value.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
switch value.Kind() {
|
||||
case reflect.Struct:
|
||||
v.validateStruct(value, path)
|
||||
case reflect.Slice:
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
v.validateAny(value.Index(i), path+fmt.Sprintf("[%d]", i))
|
||||
}
|
||||
case reflect.Map:
|
||||
for _, n := range value.MapKeys() {
|
||||
v.validateAny(value.MapIndex(n), path+fmt.Sprintf("[%q]", n.String()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// validateStruct will validate the struct value's fields. If the structure has
|
||||
// nested types those types will be validated also.
|
||||
func (v *validator) validateStruct(value reflect.Value, path string) {
|
||||
prefix := "."
|
||||
if path == "" {
|
||||
prefix = ""
|
||||
}
|
||||
|
||||
for i := 0; i < value.Type().NumField(); i++ {
|
||||
f := value.Type().Field(i)
|
||||
if strings.ToLower(f.Name[0:1]) == f.Name[0:1] {
|
||||
continue
|
||||
}
|
||||
fvalue := value.FieldByName(f.Name)
|
||||
|
||||
notset := false
|
||||
notval := false
|
||||
if f.Tag.Get("required") != "" {
|
||||
switch fvalue.Kind() {
|
||||
case reflect.Ptr:
|
||||
if fvalue.IsNil() {
|
||||
notset = true
|
||||
} else {
|
||||
elem := fvalue.Elem()
|
||||
if elem.Kind() == reflect.String && elem.Len() == 0 {
|
||||
notval = true
|
||||
}
|
||||
}
|
||||
case reflect.Slice, reflect.Map:
|
||||
if fvalue.IsNil() {
|
||||
notset = true
|
||||
}
|
||||
default:
|
||||
if !fvalue.IsValid() {
|
||||
notset = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if notset {
|
||||
msg := "missing required parameter: " + path + prefix + f.Name
|
||||
v.errors = append(v.errors, msg)
|
||||
} else if notval {
|
||||
msg := "input member " + path + prefix + f.Name + " must not be empty"
|
||||
v.errors = append(v.errors, msg)
|
||||
} else {
|
||||
v.validateAny(fvalue, path+prefix+f.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
96
vendor/github.com/ks3sdklib/aws-sdk-go/aws/progress.go
generated
vendored
Normal file
96
vendor/github.com/ks3sdklib/aws-sdk-go/aws/progress.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ProgressFunc func(increment, completed, total int64)
|
||||
|
||||
type teeReader struct {
|
||||
reader io.Reader
|
||||
writer io.Writer
|
||||
tracker *readerTracker
|
||||
}
|
||||
|
||||
type readerTracker struct {
|
||||
completedBytes int64
|
||||
totalBytes int64
|
||||
progressFunc ProgressFunc
|
||||
}
|
||||
|
||||
// TeeReader returns a Reader that writes to w what it reads from r.
|
||||
// All reads from r performed through it are matched with
|
||||
// corresponding writes to w. There is no internal buffering -
|
||||
// to write must complete before the read completes.
|
||||
// Any error encountered while writing is reported as a read error.
|
||||
func TeeReader(reader io.Reader, writer io.Writer, totalBytes int64, progressFunc ProgressFunc) io.ReadCloser {
|
||||
return &teeReader{
|
||||
reader: reader,
|
||||
writer: writer,
|
||||
tracker: &readerTracker{
|
||||
completedBytes: 0,
|
||||
totalBytes: totalBytes,
|
||||
progressFunc: progressFunc,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (t *teeReader) Read(p []byte) (n int, err error) {
|
||||
n, err = t.reader.Read(p)
|
||||
|
||||
// Read encountered error
|
||||
if err != nil && err != io.EOF {
|
||||
return
|
||||
}
|
||||
|
||||
if n > 0 {
|
||||
// update completedBytes
|
||||
t.tracker.completedBytes += int64(n)
|
||||
|
||||
if t.tracker.progressFunc != nil {
|
||||
// report progress
|
||||
t.tracker.progressFunc(int64(n), t.tracker.completedBytes, t.tracker.totalBytes)
|
||||
}
|
||||
// CRC
|
||||
if t.writer != nil {
|
||||
if n, err := t.writer.Write(p[:n]); err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (t *teeReader) Close() error {
|
||||
if rc, ok := t.reader.(io.ReadCloser); ok {
|
||||
return rc.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetReaderLen returns the length of the reader
|
||||
func GetReaderLen(reader io.Reader) int64 {
|
||||
var contentLength int64
|
||||
switch v := reader.(type) {
|
||||
case *bytes.Buffer:
|
||||
contentLength = int64(v.Len())
|
||||
case *bytes.Reader:
|
||||
contentLength = int64(v.Len())
|
||||
case *strings.Reader:
|
||||
contentLength = int64(v.Len())
|
||||
case *os.File:
|
||||
fileInfo, err := v.Stat()
|
||||
if err != nil {
|
||||
contentLength = 0
|
||||
} else {
|
||||
contentLength = fileInfo.Size()
|
||||
}
|
||||
default:
|
||||
contentLength = 0
|
||||
}
|
||||
return contentLength
|
||||
}
|
||||
326
vendor/github.com/ks3sdklib/aws-sdk-go/aws/request.go
generated
vendored
Normal file
326
vendor/github.com/ks3sdklib/aws-sdk-go/aws/request.go
generated
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/awsutil"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/crc"
|
||||
"hash"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// A Request is the service request to be made.
|
||||
type Request struct {
|
||||
*Service
|
||||
Handlers Handlers
|
||||
Time time.Time
|
||||
ExpireTime int64
|
||||
Operation *Operation
|
||||
HTTPRequest *http.Request
|
||||
HTTPResponse *http.Response
|
||||
Body io.ReadSeeker
|
||||
bodyStart int64 // offset from beginning of Body that the request body starts
|
||||
Params interface{}
|
||||
Error error
|
||||
Data interface{}
|
||||
RequestID string
|
||||
RetryCount uint
|
||||
Retryable SettableBool
|
||||
RetryDelay time.Duration
|
||||
built bool
|
||||
context Context
|
||||
Crc64 hash.Hash64
|
||||
ProgressFn ProgressFunc
|
||||
ContentType string
|
||||
RequestType string
|
||||
}
|
||||
|
||||
// An Operation is the service API operation to be made.
|
||||
type Operation struct {
|
||||
Name string
|
||||
HTTPMethod string
|
||||
HTTPPath string
|
||||
*Paginator
|
||||
}
|
||||
|
||||
// Paginator keeps track of pagination configuration for an API operation.
|
||||
type Paginator struct {
|
||||
InputTokens []string
|
||||
OutputTokens []string
|
||||
LimitToken string
|
||||
TruncationToken string
|
||||
}
|
||||
|
||||
// NewRequest returns a new Request pointer for the service API
|
||||
// operation and parameters.
|
||||
//
|
||||
// Params is any value of input parameters to be the request payload.
|
||||
// Data is pointer value to an object which the request's response
|
||||
// payload will be deserialized to.
|
||||
func NewRequest(service *Service, operation *Operation, params interface{}, data interface{}) *Request {
|
||||
method := operation.HTTPMethod
|
||||
if method == "" {
|
||||
method = "POST"
|
||||
}
|
||||
p := operation.HTTPPath
|
||||
if p == "" {
|
||||
p = "/"
|
||||
}
|
||||
|
||||
httpReq, _ := http.NewRequest(method, "", nil)
|
||||
httpReq.URL, _ = url.Parse(service.Endpoint + p)
|
||||
|
||||
r := &Request{
|
||||
Service: service,
|
||||
Handlers: service.Handlers.copy(),
|
||||
Time: time.Now(),
|
||||
ExpireTime: 0,
|
||||
Operation: operation,
|
||||
HTTPRequest: httpReq,
|
||||
Body: nil,
|
||||
Params: params,
|
||||
Error: nil,
|
||||
Data: data,
|
||||
}
|
||||
r.SetBufferBody([]byte{})
|
||||
return r
|
||||
}
|
||||
|
||||
func NewRequestV2(service *Service, method string, params interface{}) *Request {
|
||||
|
||||
httpReq, _ := http.NewRequest(method, "", nil)
|
||||
httpReq.URL, _ = url.Parse(service.Endpoint)
|
||||
r := &Request{
|
||||
Service: service,
|
||||
ExpireTime: 0,
|
||||
HTTPRequest: httpReq,
|
||||
Params: params,
|
||||
Error: nil,
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// WillRetry returns if the request's can be retried.
|
||||
func (r *Request) WillRetry() bool {
|
||||
return r.Error != nil && r.Retryable.Get() && int(r.RetryCount) < r.Service.MaxRetries
|
||||
}
|
||||
|
||||
// ParamsFilled returns if the request's parameters have been populated
|
||||
// and the parameters are valid. False is returned if no parameters are
|
||||
// provided or invalid.
|
||||
func (r *Request) ParamsFilled() bool {
|
||||
return r.Params != nil && reflect.ValueOf(r.Params).Elem().IsValid()
|
||||
}
|
||||
|
||||
// DataFilled returns true if the request's data for response deserialization
|
||||
// target has been set and is a valid. False is returned if data is not
|
||||
// set, or is invalid.
|
||||
func (r *Request) DataFilled() bool {
|
||||
return r.Data != nil && reflect.ValueOf(r.Data).Elem().IsValid()
|
||||
}
|
||||
|
||||
// SetBufferBody will set the request's body bytes that will be sent to
|
||||
// the service API.
|
||||
func (r *Request) SetBufferBody(buf []byte) {
|
||||
r.SetReaderBody(bytes.NewReader(buf))
|
||||
}
|
||||
|
||||
// SetStringBody sets the body of the request to be backed by a string.
|
||||
func (r *Request) SetStringBody(s string) {
|
||||
r.SetReaderBody(strings.NewReader(s))
|
||||
}
|
||||
|
||||
// SetReaderBody will set the request's body reader.
|
||||
func (r *Request) SetReaderBody(reader io.ReadSeeker) {
|
||||
if r.Config.CrcCheckEnabled {
|
||||
r.Crc64 = crc.NewCRC(crc.CrcTable(), 0)
|
||||
}
|
||||
if r.Config.CrcCheckEnabled || r.ProgressFn != nil {
|
||||
r.HTTPRequest.Body = TeeReader(reader, r.Crc64, GetReaderLen(reader), r.ProgressFn)
|
||||
} else {
|
||||
r.HTTPRequest.Body = io.NopCloser(reader)
|
||||
}
|
||||
r.Body = reader
|
||||
}
|
||||
|
||||
// Build will build the request's object, so it can be signed and sent
|
||||
// to the service. Build will also validate all the request's parameters.
|
||||
// Anny additional build Handlers set on this request will be run
|
||||
// in the order they were set.
|
||||
//
|
||||
// The request will only be built once. Multiple calls to build will have
|
||||
// no effect.
|
||||
//
|
||||
// If any Validate or Build errors occur the build will stop and the error
|
||||
// which occurred will be returned.
|
||||
func (r *Request) Build() error {
|
||||
if !r.built {
|
||||
r.Error = nil
|
||||
r.Handlers.Validate.Run(r)
|
||||
if r.Error != nil {
|
||||
return r.Error
|
||||
}
|
||||
r.Handlers.Build.Run(r)
|
||||
r.built = true
|
||||
}
|
||||
|
||||
return r.Error
|
||||
}
|
||||
|
||||
// Sign will sign the request retuning error if errors are encountered.
|
||||
//
|
||||
// Send will build the request prior to signing. All Sign Handlers will
|
||||
// be executed in the order they were set.
|
||||
func (r *Request) Sign() error {
|
||||
r.Build()
|
||||
if r.Error != nil {
|
||||
return r.Error
|
||||
}
|
||||
|
||||
r.Handlers.Sign.Run(r)
|
||||
return r.Error
|
||||
}
|
||||
|
||||
// Send will send the request returning error if errors are encountered.
|
||||
//
|
||||
// Send will sign the request prior to sending. All Send Handlers will
|
||||
// be executed in the order they were set.
|
||||
func (r *Request) Send() error {
|
||||
for {
|
||||
r.Sign()
|
||||
|
||||
if r.Error != nil {
|
||||
return r.Error
|
||||
}
|
||||
if r.Retryable.Get() {
|
||||
// Re-seek the body back to the original point in for a retry so that
|
||||
// send will send the body's contents again in the upcoming request.
|
||||
r.Body.Seek(r.bodyStart, 0)
|
||||
}
|
||||
r.Retryable.Reset()
|
||||
|
||||
r.Handlers.Send.Run(r)
|
||||
if r.Error != nil {
|
||||
r.Handlers.Retry.Run(r)
|
||||
r.Handlers.AfterRetry.Run(r)
|
||||
if r.Error != nil {
|
||||
return r.Error
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
r.Handlers.UnmarshalMeta.Run(r)
|
||||
r.Handlers.ValidateResponse.Run(r)
|
||||
if r.Error != nil {
|
||||
r.Handlers.UnmarshalError.Run(r)
|
||||
r.Handlers.Retry.Run(r)
|
||||
r.Handlers.AfterRetry.Run(r)
|
||||
if r.Error != nil {
|
||||
return r.Error
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
r.Handlers.Unmarshal.Run(r)
|
||||
r.Handlers.CheckCrc64.Run(r)
|
||||
if r.Error != nil {
|
||||
r.Handlers.Retry.Run(r)
|
||||
r.Handlers.AfterRetry.Run(r)
|
||||
if r.Error != nil {
|
||||
return r.Error
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasNextPage returns true if this request has more pages of data available.
|
||||
func (r *Request) HasNextPage() bool {
|
||||
return r.nextPageTokens() != nil
|
||||
}
|
||||
|
||||
// nextPageTokens returns the tokens to use when asking for the next page of
|
||||
// data.
|
||||
func (r *Request) nextPageTokens() []interface{} {
|
||||
if r.Operation.Paginator == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if r.Operation.TruncationToken != "" {
|
||||
tr := awsutil.ValuesAtAnyPath(r.Data, r.Operation.TruncationToken)
|
||||
if tr == nil || len(tr) == 0 {
|
||||
return nil
|
||||
}
|
||||
switch v := tr[0].(type) {
|
||||
case bool:
|
||||
if v == false {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
found := false
|
||||
tokens := make([]interface{}, len(r.Operation.OutputTokens))
|
||||
|
||||
for i, outtok := range r.Operation.OutputTokens {
|
||||
v := awsutil.ValuesAtAnyPath(r.Data, outtok)
|
||||
if v != nil && len(v) > 0 {
|
||||
found = true
|
||||
tokens[i] = v[0]
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
return tokens
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NextPage returns a new Request that can be executed to return the next
|
||||
// page of result data. Call .Send() on this request to execute it.
|
||||
func (r *Request) NextPage() *Request {
|
||||
tokens := r.nextPageTokens()
|
||||
if tokens == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
data := reflect.New(reflect.TypeOf(r.Data).Elem()).Interface()
|
||||
nr := NewRequest(r.Service, r.Operation, awsutil.CopyOf(r.Params), data)
|
||||
for i, intok := range nr.Operation.InputTokens {
|
||||
awsutil.SetValueAtAnyPath(nr.Params, intok, tokens[i])
|
||||
}
|
||||
return nr
|
||||
}
|
||||
|
||||
// EachPage iterates over each page of a paginated request object. The fn
|
||||
// parameter should be a function with the following sample signature:
|
||||
//
|
||||
// func(page *T, lastPage bool) bool {
|
||||
// return true // return false to stop iterating
|
||||
// }
|
||||
//
|
||||
// Where "T" is the structure type matching the output structure of the given
|
||||
// operation. For example, a request object generated by
|
||||
// DynamoDB.ListTablesRequest() would expect to see dynamodb.ListTablesOutput
|
||||
// as the structure "T". The lastPage value represents whether the page is
|
||||
// the last page of data or not. The return value of this function should
|
||||
// return true to keep iterating or false to stop.
|
||||
func (r *Request) EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error {
|
||||
for page := r; page != nil; page = page.NextPage() {
|
||||
page.Send()
|
||||
shouldContinue := fn(page.Data, !page.HasNextPage())
|
||||
if page.Error != nil || !shouldContinue {
|
||||
return page.Error
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
37
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/exponential_retry.go
generated
vendored
Normal file
37
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/exponential_retry.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
package retry
|
||||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ExponentialRetryRule 指数级增长等待时间重试规则
|
||||
type ExponentialRetryRule struct {
|
||||
baseDelay time.Duration // 基础等待时间
|
||||
maxDelay time.Duration // 单次最大等待时间
|
||||
}
|
||||
|
||||
var DefaultExponentialRetryRule = NewExponentialRetryRule(DefaultBaseDelay, DefaultMaxDelay)
|
||||
|
||||
func NewExponentialRetryRule(baseDelay time.Duration, maxDelay time.Duration) ExponentialRetryRule {
|
||||
if baseDelay < 0 {
|
||||
baseDelay = DefaultBaseDelay
|
||||
}
|
||||
|
||||
if maxDelay < 0 {
|
||||
maxDelay = DefaultMaxDelay
|
||||
}
|
||||
|
||||
return ExponentialRetryRule{
|
||||
baseDelay: baseDelay,
|
||||
maxDelay: maxDelay,
|
||||
}
|
||||
}
|
||||
|
||||
func (r ExponentialRetryRule) GetDelay(attempts int) time.Duration {
|
||||
delay := r.baseDelay * time.Duration(math.Pow(2, float64(attempts-1)))
|
||||
if delay > r.maxDelay {
|
||||
return r.maxDelay
|
||||
}
|
||||
return delay
|
||||
}
|
||||
26
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/fixed_retry.go
generated
vendored
Normal file
26
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/fixed_retry.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
package retry
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// FixedRetryRule 固定等待时间重试规则
|
||||
type FixedRetryRule struct {
|
||||
baseDelay time.Duration // 基础等待时间
|
||||
}
|
||||
|
||||
var DefaultFixedRetryRule = NewFixedRetryRule(DefaultBaseDelay)
|
||||
|
||||
func NewFixedRetryRule(baseDelay time.Duration) FixedRetryRule {
|
||||
if baseDelay < 0 {
|
||||
baseDelay = DefaultBaseDelay
|
||||
}
|
||||
|
||||
return FixedRetryRule{
|
||||
baseDelay: baseDelay,
|
||||
}
|
||||
}
|
||||
|
||||
func (r FixedRetryRule) GetDelay(attempts int) time.Duration {
|
||||
return r.baseDelay
|
||||
}
|
||||
36
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/linear_retry.go
generated
vendored
Normal file
36
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/linear_retry.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
package retry
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// LinearRetryRule 线性增长等待时间重试规则
|
||||
type LinearRetryRule struct {
|
||||
baseDelay time.Duration // 基础等待时间
|
||||
maxDelay time.Duration // 单次最大等待时间
|
||||
}
|
||||
|
||||
var DefaultLinearRetryRule = NewLinearRetryRule(DefaultBaseDelay, DefaultMaxDelay)
|
||||
|
||||
func NewLinearRetryRule(baseDelay time.Duration, maxDelay time.Duration) LinearRetryRule {
|
||||
if baseDelay < 0 {
|
||||
baseDelay = DefaultBaseDelay
|
||||
}
|
||||
|
||||
if maxDelay < 0 {
|
||||
maxDelay = DefaultMaxDelay
|
||||
}
|
||||
|
||||
return LinearRetryRule{
|
||||
baseDelay: baseDelay,
|
||||
maxDelay: maxDelay,
|
||||
}
|
||||
}
|
||||
|
||||
func (r LinearRetryRule) GetDelay(attempts int) time.Duration {
|
||||
delay := r.baseDelay * time.Duration(attempts)
|
||||
if delay > r.maxDelay {
|
||||
return r.maxDelay
|
||||
}
|
||||
return delay
|
||||
}
|
||||
18
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/no_delay_retry.go
generated
vendored
Normal file
18
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/no_delay_retry.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
package retry
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// NoDelayRetryRule 不等待重试规则(立即重试)
|
||||
type NoDelayRetryRule struct{}
|
||||
|
||||
var DefaultNoDelayRetryRule = NewNoDelayRetryRule()
|
||||
|
||||
func NewNoDelayRetryRule() NoDelayRetryRule {
|
||||
return NoDelayRetryRule{}
|
||||
}
|
||||
|
||||
func (r NoDelayRetryRule) GetDelay(attempts int) time.Duration {
|
||||
return 0
|
||||
}
|
||||
39
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/random_retry.go
generated
vendored
Normal file
39
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/random_retry.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
package retry
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RandomRetryRule 随机等待时间重试规则
|
||||
type RandomRetryRule struct {
|
||||
minDelay time.Duration // 最小随机等待时间
|
||||
maxDelay time.Duration // 最大随机等待时间
|
||||
}
|
||||
|
||||
var DefaultRandomRetryRule = NewRandomRetryRule(DefaultRandomMinDelay, DefaultRandomMaxDelay)
|
||||
|
||||
func NewRandomRetryRule(minDelay time.Duration, maxDelay time.Duration) RandomRetryRule {
|
||||
if minDelay < 0 {
|
||||
minDelay = DefaultRandomMinDelay
|
||||
}
|
||||
|
||||
if maxDelay < 0 {
|
||||
maxDelay = DefaultRandomMaxDelay
|
||||
}
|
||||
|
||||
if maxDelay < minDelay {
|
||||
minDelay = DefaultRandomMinDelay
|
||||
maxDelay = DefaultRandomMaxDelay
|
||||
}
|
||||
|
||||
return RandomRetryRule{
|
||||
minDelay: minDelay,
|
||||
maxDelay: maxDelay,
|
||||
}
|
||||
}
|
||||
|
||||
func (r RandomRetryRule) GetDelay(attempts int) time.Duration {
|
||||
delay := r.minDelay + time.Duration(rand.Int63n(int64(r.maxDelay-r.minDelay+1)))
|
||||
return delay
|
||||
}
|
||||
19
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/retry.go
generated
vendored
Normal file
19
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/retry.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
package retry
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
// DefaultMaxDelay 默认最大等待时间
|
||||
DefaultMaxDelay = 20 * time.Second
|
||||
// DefaultBaseDelay 默认基础等待时间
|
||||
DefaultBaseDelay = 200 * time.Millisecond
|
||||
// DefaultRandomMinDelay 默认随机最小等待时间
|
||||
DefaultRandomMinDelay = 0
|
||||
// DefaultRandomMaxDelay 默认随机最大等待时间
|
||||
DefaultRandomMaxDelay = 200 * time.Millisecond
|
||||
)
|
||||
|
||||
// RetryRule 重试等待规则
|
||||
type RetryRule interface {
|
||||
GetDelay(attempts int) time.Duration
|
||||
}
|
||||
69
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/retryable_error.go
generated
vendored
Normal file
69
vendor/github.com/ks3sdklib/aws-sdk-go/aws/retry/retryable_error.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
package retry
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/awserr"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
)
|
||||
|
||||
// ShouldRetry 判断是否需要重试
|
||||
// 重试条件:
|
||||
// 1.状态码为5xx
|
||||
// 2.状态码在retryErrorCodes中
|
||||
// 3.错误码在retryableCodes中
|
||||
func ShouldRetry(err error) bool {
|
||||
var requestError *apierr.RequestError
|
||||
if errors.As(err, &requestError) {
|
||||
if requestError.StatusCode() >= 500 {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, code := range retryErrorCodes {
|
||||
if requestError.StatusCode() == code {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err, ok := err.(awserr.Error); ok {
|
||||
return IsCodeRetryable(err.Code())
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 重试错误码
|
||||
var retryErrorCodes = []int{
|
||||
408, // RequestTimeout
|
||||
429, // TooManyRequests
|
||||
}
|
||||
|
||||
// retryableCodes is a collection of service response codes which are retry-able
|
||||
// without any further action.
|
||||
var retryableCodes = map[string]struct{}{
|
||||
"RequestError": {},
|
||||
"ProvisionedThroughputExceededException": {},
|
||||
"Throttling": {},
|
||||
}
|
||||
|
||||
// credsExpiredCodes is a collection of error codes which signify the credentials
|
||||
// need to be refreshed. Expired tokens require refreshing of credentials, and
|
||||
// resigning before the request can be retried.
|
||||
var credsExpiredCodes = map[string]struct{}{
|
||||
"ExpiredToken": {},
|
||||
"ExpiredTokenException": {},
|
||||
"RequestExpired": {},
|
||||
}
|
||||
|
||||
func IsCodeRetryable(code string) bool {
|
||||
if _, ok := retryableCodes[code]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
return IsCodeExpiredCreds(code)
|
||||
}
|
||||
|
||||
func IsCodeExpiredCreds(code string) bool {
|
||||
_, ok := credsExpiredCodes[code]
|
||||
return ok
|
||||
}
|
||||
112
vendor/github.com/ks3sdklib/aws-sdk-go/aws/service.go
generated
vendored
Normal file
112
vendor/github.com/ks3sdklib/aws-sdk-go/aws/service.go
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/retry"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/endpoints"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// A Service implements the base service request and response handling
|
||||
// used by all services.
|
||||
type Service struct {
|
||||
Config *Config
|
||||
Handlers Handlers
|
||||
ManualSend bool
|
||||
ServiceName string
|
||||
APIVersion string
|
||||
Endpoint string
|
||||
SigningName string
|
||||
SigningRegion string
|
||||
JSONVersion string
|
||||
TargetPrefix string
|
||||
RetryRule retry.RetryRule
|
||||
ShouldRetry func(error) bool
|
||||
MaxRetries int
|
||||
}
|
||||
|
||||
var schemeRE = regexp.MustCompile("^([^:]+)://")
|
||||
|
||||
// NewService will return a pointer to a new Server object initialized.
|
||||
func NewService(config *Config) *Service {
|
||||
svc := &Service{Config: config}
|
||||
svc.Initialize()
|
||||
return svc
|
||||
}
|
||||
|
||||
// Initialize initializes the service.
|
||||
func (s *Service) Initialize() {
|
||||
if s.Config == nil {
|
||||
s.Config = &Config{}
|
||||
}
|
||||
if s.Config.HTTPClient == nil {
|
||||
s.Config.HTTPClient = http.DefaultClient
|
||||
}
|
||||
|
||||
if s.RetryRule == nil {
|
||||
s.RetryRule = s.Config.RetryRule
|
||||
}
|
||||
|
||||
if s.ShouldRetry == nil {
|
||||
s.ShouldRetry = s.Config.ShouldRetry
|
||||
}
|
||||
|
||||
s.MaxRetries = s.Config.MaxRetries
|
||||
s.Handlers.Validate.PushBack(ValidateEndpointHandler)
|
||||
s.Handlers.Build.PushBack(UserAgentHandler)
|
||||
s.Handlers.Sign.PushBack(BuildContentLength)
|
||||
s.Handlers.Send.PushBack(SendHandler)
|
||||
s.Handlers.AfterRetry.PushBack(AfterRetryHandler)
|
||||
s.Handlers.ValidateResponse.PushBack(ValidateResponseHandler)
|
||||
s.AddDebugHandlers()
|
||||
s.buildEndpoint()
|
||||
|
||||
if !s.Config.DisableParamValidation {
|
||||
s.Handlers.Validate.PushBack(ValidateParameters)
|
||||
}
|
||||
}
|
||||
|
||||
// buildEndpoint builds the endpoint values the service will use to make requests with.
|
||||
func (s *Service) buildEndpoint() {
|
||||
if s.Config.Endpoint != "" {
|
||||
s.Endpoint = s.Config.Endpoint
|
||||
} else {
|
||||
s.Endpoint, s.SigningRegion =
|
||||
endpoints.EndpointForRegion(s.ServiceName, s.Config.Region)
|
||||
}
|
||||
if s.Endpoint != "" && !schemeRE.MatchString(s.Endpoint) {
|
||||
scheme := "https"
|
||||
if s.Config.DisableSSL {
|
||||
scheme = "http"
|
||||
}
|
||||
s.Endpoint = scheme + "://" + s.Endpoint
|
||||
}
|
||||
}
|
||||
|
||||
// AddDebugHandlers injects debug logging handlers into the service to log request
|
||||
// debug information.
|
||||
func (s *Service) AddDebugHandlers() {
|
||||
if s.Config.LogLevel < Debug {
|
||||
return
|
||||
}
|
||||
|
||||
s.Handlers.Send.PushFront(func(r *Request) {
|
||||
logBody := r.Config.LogHTTPBody
|
||||
dumpedBody, _ := httputil.DumpRequestOut(r.HTTPRequest, logBody)
|
||||
r.Config.LogDebug("---[ REQUEST ]-----------------------------")
|
||||
r.Config.LogDebug("%s", string(dumpedBody))
|
||||
r.Config.LogDebug("-----------------------------------------------------")
|
||||
})
|
||||
s.Handlers.Send.PushBack(func(r *Request) {
|
||||
r.Config.LogDebug("---[ RESPONSE ]--------------------------------------")
|
||||
if r.HTTPResponse != nil {
|
||||
logBody := r.Config.LogHTTPBody
|
||||
dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody)
|
||||
r.Config.LogDebug("%s", string(dumpedBody))
|
||||
} else if r.Error != nil {
|
||||
r.Config.LogDebug("%s", r.Error.Error())
|
||||
}
|
||||
r.Config.LogDebug("-----------------------------------------------------")
|
||||
})
|
||||
}
|
||||
167
vendor/github.com/ks3sdklib/aws-sdk-go/aws/types.go
generated
vendored
Normal file
167
vendor/github.com/ks3sdklib/aws-sdk-go/aws/types.go
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
// String converts a Go string into a string pointer.
|
||||
func String(v string) *string {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToString converts a string pointer into a string.
|
||||
func ToString(p *string) (v string) {
|
||||
if p == nil {
|
||||
return v
|
||||
}
|
||||
|
||||
return *p
|
||||
}
|
||||
|
||||
// Boolean converts a Go bool into a boolean pointer.
|
||||
func Boolean(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToBoolean converts a boolean pointer into a bool.
|
||||
func ToBoolean(p *bool) (v bool) {
|
||||
if p == nil {
|
||||
return v
|
||||
}
|
||||
|
||||
return *p
|
||||
}
|
||||
|
||||
// Long converts a Go int64 into a long pointer.
|
||||
func Long(v int64) *int64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToLong converts a long pointer into a int64.
|
||||
func ToLong(p *int64) (v int64) {
|
||||
if p == nil {
|
||||
return v
|
||||
}
|
||||
|
||||
return *p
|
||||
}
|
||||
|
||||
// Double converts a Go float64 into a double pointer.
|
||||
func Double(v float64) *float64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// ToDouble converts a double pointer into a float64.
|
||||
func ToDouble(p *float64) (v float64) {
|
||||
if p == nil {
|
||||
return v
|
||||
}
|
||||
|
||||
return *p
|
||||
}
|
||||
|
||||
// Time converts a Go Time into a Time pointer
|
||||
func Time(t time.Time) *time.Time {
|
||||
return &t
|
||||
}
|
||||
|
||||
// ReadSeekCloser wraps a io.Reader returning a ReaderSeakerCloser
|
||||
func ReadSeekCloser(r io.Reader) ReaderSeekerCloser {
|
||||
return ReaderSeekerCloser{r}
|
||||
}
|
||||
|
||||
// ReaderSeekerCloser represents a reader that can also delegate io.Seeker and
|
||||
// io.Closer interfaces to the underlying object if they are available.
|
||||
type ReaderSeekerCloser struct {
|
||||
r io.Reader
|
||||
}
|
||||
|
||||
// Read reads from the reader up to size of p. The number of bytes read, and
|
||||
// error if it occurred will be returned.
|
||||
//
|
||||
// If the reader is not an io.Reader zero bytes read, and nil error will be returned.
|
||||
//
|
||||
// Performs the same functionality as io.Reader Read
|
||||
func (r ReaderSeekerCloser) Read(p []byte) (int, error) {
|
||||
switch t := r.r.(type) {
|
||||
case io.Reader:
|
||||
return t.Read(p)
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Seek sets the offset for the next Read to offset, interpreted according to
|
||||
// whence: 0 means relative to the origin of the file, 1 means relative to the
|
||||
// current offset, and 2 means relative to the end. Seek returns the new offset
|
||||
// and an error, if any.
|
||||
//
|
||||
// If the ReaderSeekerCloser is not an io.Seeker nothing will be done.
|
||||
func (r ReaderSeekerCloser) Seek(offset int64, whence int) (int64, error) {
|
||||
switch t := r.r.(type) {
|
||||
case io.Seeker:
|
||||
return t.Seek(offset, whence)
|
||||
}
|
||||
return int64(0), nil
|
||||
}
|
||||
|
||||
// Close closes the ReaderSeekerCloser.
|
||||
//
|
||||
// If the ReaderSeekerCloser is not an io.Closer nothing will be done.
|
||||
func (r ReaderSeekerCloser) Close() error {
|
||||
switch t := r.r.(type) {
|
||||
case io.Closer:
|
||||
return t.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A SettableBool provides a boolean value which includes the state if
|
||||
// the value was set or unset. The set state is in addition to the value's
|
||||
// value(true|false)
|
||||
type SettableBool struct {
|
||||
value bool
|
||||
set bool
|
||||
}
|
||||
|
||||
// SetBool returns a SettableBool with a value set
|
||||
func SetBool(value bool) SettableBool {
|
||||
return SettableBool{value: value, set: true}
|
||||
}
|
||||
|
||||
// Get returns the value. Will always be false if the SettableBool was not set.
|
||||
func (b *SettableBool) Get() bool {
|
||||
if !b.set {
|
||||
return false
|
||||
}
|
||||
return b.value
|
||||
}
|
||||
|
||||
// Set sets the value and updates the state that the value has been set.
|
||||
func (b *SettableBool) Set(value bool) {
|
||||
b.value = value
|
||||
b.set = true
|
||||
}
|
||||
|
||||
// IsSet returns if the value has been set
|
||||
func (b *SettableBool) IsSet() bool {
|
||||
return b.set
|
||||
}
|
||||
|
||||
// Reset resets the state and value of the SettableBool to its initial default
|
||||
// state of not set and zero value.
|
||||
func (b *SettableBool) Reset() {
|
||||
b.value = false
|
||||
b.set = false
|
||||
}
|
||||
|
||||
// String returns the string representation of the value if set. Zero if not set.
|
||||
func (b *SettableBool) String() string {
|
||||
return fmt.Sprintf("%t", b.Get())
|
||||
}
|
||||
|
||||
// GoString returns the string representation of the SettableBool value and state
|
||||
func (b *SettableBool) GoString() string {
|
||||
return fmt.Sprintf("Bool{value:%t, set:%t}", b.value, b.set)
|
||||
}
|
||||
7
vendor/github.com/ks3sdklib/aws-sdk-go/aws/version.go
generated
vendored
Normal file
7
vendor/github.com/ks3sdklib/aws-sdk-go/aws/version.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package aws
|
||||
|
||||
// SDKName is the name of this KS3 SDK
|
||||
const SDKName = "ks3-sdk-go"
|
||||
|
||||
// SDKVersion is the version of this SDK
|
||||
const SDKVersion = "1.8.1"
|
||||
139
vendor/github.com/ks3sdklib/aws-sdk-go/internal/apierr/error.go
generated
vendored
Normal file
139
vendor/github.com/ks3sdklib/aws-sdk-go/internal/apierr/error.go
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
// Package apierr represents API error types.
|
||||
package apierr
|
||||
|
||||
import "fmt"
|
||||
|
||||
// A BaseError wraps the code and message which defines an error. It also
|
||||
// can be used to wrap an original error object.
|
||||
//
|
||||
// Should be used as the root for errors satisfying the awserr.Error. Also
|
||||
// for any error which does not fit into a specific error wrapper type.
|
||||
type BaseError struct {
|
||||
// Classification of error
|
||||
code string
|
||||
|
||||
// Detailed information about error
|
||||
message string
|
||||
|
||||
// Optional original error this error is based off of. Allows building
|
||||
// chained errors.
|
||||
origErr error
|
||||
}
|
||||
|
||||
// New returns an error object for the code, message, and err.
|
||||
//
|
||||
// code is a short no whitespace phrase depicting the classification of
|
||||
// the error that is being created.
|
||||
//
|
||||
// message is the free flow string containing detailed information about the error.
|
||||
//
|
||||
// origErr is the error object which will be nested under the new error to be returned.
|
||||
func New(code, message string, origErr error) *BaseError {
|
||||
return &BaseError{
|
||||
code: code,
|
||||
message: message,
|
||||
origErr: origErr,
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns the string representation of the error.
|
||||
//
|
||||
// See ErrorWithExtra for formatting.
|
||||
//
|
||||
// Satisfies the error interface.
|
||||
func (b *BaseError) Error() string {
|
||||
return b.ErrorWithExtra("")
|
||||
}
|
||||
|
||||
// String returns the string representation of the error.
|
||||
// Alias for Error to satisfy the stringer interface.
|
||||
func (b *BaseError) String() string {
|
||||
return b.Error()
|
||||
}
|
||||
|
||||
// Code returns the short phrase depicting the classification of the error.
|
||||
func (b *BaseError) Code() string {
|
||||
return b.code
|
||||
}
|
||||
|
||||
// Message returns the error details message.
|
||||
func (b *BaseError) Message() string {
|
||||
return b.message
|
||||
}
|
||||
|
||||
// OrigErr returns the original error if one was set. Nil is returned if no error
|
||||
// was set.
|
||||
func (b *BaseError) OrigErr() error {
|
||||
return b.origErr
|
||||
}
|
||||
|
||||
// ErrorWithExtra is a helper method to add an extra string to the stratified
|
||||
// error message. The extra message will be added on the next line below the
|
||||
// error message like the following:
|
||||
//
|
||||
// <error code>: <error message>
|
||||
// <extra message>
|
||||
//
|
||||
// If there is a original error the error will be included on a new line.
|
||||
//
|
||||
// <error code>: <error message>
|
||||
// <extra message>
|
||||
// caused by: <original error>
|
||||
func (b *BaseError) ErrorWithExtra(extra string) string {
|
||||
msg := fmt.Sprintf("%s: %s", b.code, b.message)
|
||||
if extra != "" {
|
||||
msg = fmt.Sprintf("%s\n\t%s", msg, extra)
|
||||
}
|
||||
if b.origErr != nil {
|
||||
msg = fmt.Sprintf("%s\ncaused by: %s", msg, b.origErr.Error())
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
// A RequestError wraps a request or service error.
|
||||
//
|
||||
// Composed of BaseError for code, message, and original error.
|
||||
type RequestError struct {
|
||||
*BaseError
|
||||
statusCode int
|
||||
requestID string
|
||||
}
|
||||
|
||||
// NewRequestError returns a wrapped error with additional information for request
|
||||
// status code, and service requestID.
|
||||
//
|
||||
// Should be used to wrap all request which involve service requests. Even if
|
||||
// the request failed without a service response, but had an HTTP status code
|
||||
// that may be meaningful.
|
||||
//
|
||||
// Also wraps original errors via the BaseError.
|
||||
func NewRequestError(base *BaseError, statusCode int, requestID string) *RequestError {
|
||||
return &RequestError{
|
||||
BaseError: base,
|
||||
statusCode: statusCode,
|
||||
requestID: requestID,
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns the string representation of the error.
|
||||
// Satisfies the error interface.
|
||||
func (r *RequestError) Error() string {
|
||||
return r.ErrorWithExtra(fmt.Sprintf("status code: %d, request id: [%s]",
|
||||
r.statusCode, r.requestID))
|
||||
}
|
||||
|
||||
// String returns the string representation of the error.
|
||||
// Alias for Error to satisfy the stringer interface.
|
||||
func (r *RequestError) String() string {
|
||||
return r.Error()
|
||||
}
|
||||
|
||||
// StatusCode returns the wrapped status code for the error
|
||||
func (r *RequestError) StatusCode() int {
|
||||
return r.statusCode
|
||||
}
|
||||
|
||||
// RequestID returns the wrapped requestID
|
||||
func (r *RequestError) RequestID() string {
|
||||
return r.requestID
|
||||
}
|
||||
127
vendor/github.com/ks3sdklib/aws-sdk-go/internal/crc/crc64.go
generated
vendored
Normal file
127
vendor/github.com/ks3sdklib/aws-sdk-go/internal/crc/crc64.go
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
package crc
|
||||
|
||||
import (
|
||||
"hash"
|
||||
"hash/crc64"
|
||||
)
|
||||
|
||||
// digest represents the partial evaluation of a checksum.
|
||||
type digest struct {
|
||||
crc uint64
|
||||
tab *crc64.Table
|
||||
}
|
||||
|
||||
// NewCRC creates a new hash.Hash64 computing the CRC64 checksum
|
||||
// using the polynomial represented by the Table.
|
||||
func NewCRC(tab *crc64.Table, init uint64) hash.Hash64 { return &digest{init, tab} }
|
||||
|
||||
var CrcTable = func() *crc64.Table {
|
||||
return crc64.MakeTable(crc64.ECMA)
|
||||
}
|
||||
|
||||
// Size returns the number of bytes sum will return.
|
||||
func (d *digest) Size() int { return crc64.Size }
|
||||
|
||||
// BlockSize returns the hash's underlying block size.
|
||||
// The Write method must be able to accept any amount
|
||||
// of data, but it may operate more efficiently if all writes
|
||||
// are a multiple of the block size.
|
||||
func (d *digest) BlockSize() int { return 1 }
|
||||
|
||||
// Reset resets the hash to its initial state.
|
||||
func (d *digest) Reset() { d.crc = 0 }
|
||||
|
||||
// Write (via the embedded io.Writer interface) adds more data to the running hash.
|
||||
// It never returns an error.
|
||||
func (d *digest) Write(p []byte) (n int, err error) {
|
||||
d.crc = crc64.Update(d.crc, d.tab, p)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// Sum64 returns CRC64 value.
|
||||
func (d *digest) Sum64() uint64 { return d.crc }
|
||||
|
||||
// Sum returns hash value.
|
||||
func (d *digest) Sum(in []byte) []byte {
|
||||
s := d.Sum64()
|
||||
return append(in, byte(s>>56), byte(s>>48), byte(s>>40), byte(s>>32), byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
|
||||
}
|
||||
|
||||
// gf2Dim dimension of GF(2) vectors (length of CRC)
|
||||
const gf2Dim int = 64
|
||||
|
||||
func gf2MatrixTimes(mat []uint64, vec uint64) uint64 {
|
||||
var sum uint64
|
||||
for i := 0; vec != 0; i++ {
|
||||
if vec&1 != 0 {
|
||||
sum ^= mat[i]
|
||||
}
|
||||
|
||||
vec >>= 1
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func gf2MatrixSquare(square []uint64, mat []uint64) {
|
||||
for n := 0; n < gf2Dim; n++ {
|
||||
square[n] = gf2MatrixTimes(mat, mat[n])
|
||||
}
|
||||
}
|
||||
|
||||
// CRC64Combine combines CRC64
|
||||
func CRC64Combine(crc1 uint64, crc2 uint64, len2 uint64) uint64 {
|
||||
var even [gf2Dim]uint64 // Even-power-of-two zeros operator
|
||||
var odd [gf2Dim]uint64 // Odd-power-of-two zeros operator
|
||||
|
||||
// Degenerate case
|
||||
if len2 == 0 {
|
||||
return crc1
|
||||
}
|
||||
|
||||
// Put operator for one zero bit in odd
|
||||
odd[0] = crc64.ECMA // CRC64 polynomial
|
||||
var row uint64 = 1
|
||||
for n := 1; n < gf2Dim; n++ {
|
||||
odd[n] = row
|
||||
row <<= 1
|
||||
}
|
||||
|
||||
// Put operator for two zero bits in even
|
||||
gf2MatrixSquare(even[:], odd[:])
|
||||
|
||||
// Put operator for four zero bits in odd
|
||||
gf2MatrixSquare(odd[:], even[:])
|
||||
|
||||
// Apply len2 zeros to crc1, first square will put the operator for one zero byte, eight zero bits, in even
|
||||
for {
|
||||
// Apply zeros operator for this bit of len2
|
||||
gf2MatrixSquare(even[:], odd[:])
|
||||
|
||||
if len2&1 != 0 {
|
||||
crc1 = gf2MatrixTimes(even[:], crc1)
|
||||
}
|
||||
|
||||
len2 >>= 1
|
||||
|
||||
// If no more bits set, then done
|
||||
if len2 == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
// Another iteration of the loop with odd and even swapped
|
||||
gf2MatrixSquare(odd[:], even[:])
|
||||
if len2&1 != 0 {
|
||||
crc1 = gf2MatrixTimes(odd[:], crc1)
|
||||
}
|
||||
len2 >>= 1
|
||||
|
||||
// If no more bits set, then done
|
||||
if len2 == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Return combined CRC
|
||||
crc1 ^= crc2
|
||||
return crc1
|
||||
}
|
||||
31
vendor/github.com/ks3sdklib/aws-sdk-go/internal/endpoints/endpoints.go
generated
vendored
Normal file
31
vendor/github.com/ks3sdklib/aws-sdk-go/internal/endpoints/endpoints.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// Package endpoints validates regional endpoints for services.
|
||||
package endpoints
|
||||
|
||||
//go:generate go run ../model/cli/gen-endpoints/main.go endpoints.json endpoints_map.go
|
||||
//go:generate gofmt -s -w endpoints_map.go
|
||||
|
||||
import "strings"
|
||||
|
||||
// EndpointForRegion returns an endpoint and its signing region for a service and region.
|
||||
// if the service and region pair are not found endpoint and signingRegion will be empty.
|
||||
func EndpointForRegion(svcName, region string) (endpoint, signingRegion string) {
|
||||
derivedKeys := []string{
|
||||
region + "/" + svcName,
|
||||
region + "/*",
|
||||
"*/" + svcName,
|
||||
"*/*",
|
||||
}
|
||||
|
||||
for _, key := range derivedKeys {
|
||||
if val, ok := endpointsMap.Endpoints[key]; ok {
|
||||
ep := val.Endpoint
|
||||
ep = strings.Replace(ep, "{region}", region, -1)
|
||||
ep = strings.Replace(ep, "{service}", svcName, -1)
|
||||
|
||||
endpoint = ep
|
||||
signingRegion = val.SigningRegion
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
89
vendor/github.com/ks3sdklib/aws-sdk-go/internal/endpoints/endpoints_map.go
generated
vendored
Normal file
89
vendor/github.com/ks3sdklib/aws-sdk-go/internal/endpoints/endpoints_map.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
package endpoints
|
||||
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
|
||||
type endpointStruct struct {
|
||||
Version int
|
||||
Endpoints map[string]endpointEntry
|
||||
}
|
||||
|
||||
type endpointEntry struct {
|
||||
Endpoint string
|
||||
SigningRegion string
|
||||
}
|
||||
|
||||
var endpointsMap = endpointStruct{
|
||||
Version: 2,
|
||||
Endpoints: map[string]endpointEntry{
|
||||
"*/*": {
|
||||
Endpoint: "{service}.{region}.amazonaws.com",
|
||||
},
|
||||
"*/cloudfront": {
|
||||
Endpoint: "cloudfront.amazonaws.com",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"*/cloudsearchdomain": {
|
||||
Endpoint: "",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"*/iam": {
|
||||
Endpoint: "iam.amazonaws.com",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"*/importexport": {
|
||||
Endpoint: "importexport.amazonaws.com",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"*/route53": {
|
||||
Endpoint: "route53.amazonaws.com",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"*/sts": {
|
||||
Endpoint: "sts.amazonaws.com",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"ap-northeast-1/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"ap-southeast-1/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"ap-southeast-2/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"cn-north-1/*": {
|
||||
Endpoint: "{service}.{region}.amazonaws.com.cn",
|
||||
},
|
||||
"eu-central-1/s3": {
|
||||
Endpoint: "{service}.{region}.amazonaws.com",
|
||||
},
|
||||
"eu-west-1/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"sa-east-1/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"us-east-1/s3": {
|
||||
Endpoint: "s3.amazonaws.com",
|
||||
},
|
||||
"us-east-1/sdb": {
|
||||
Endpoint: "sdb.amazonaws.com",
|
||||
SigningRegion: "us-east-1",
|
||||
},
|
||||
"us-gov-west-1/iam": {
|
||||
Endpoint: "iam.us-gov.amazonaws.com",
|
||||
},
|
||||
"us-gov-west-1/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"us-gov-west-1/sts": {
|
||||
Endpoint: "sts.us-gov-west-1.amazonaws.com",
|
||||
},
|
||||
"us-west-1/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
"us-west-2/s3": {
|
||||
Endpoint: "s3-{region}.amazonaws.com",
|
||||
},
|
||||
},
|
||||
}
|
||||
37
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/body/body.go
generated
vendored
Normal file
37
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/body/body.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
package body
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/rest"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/restjson"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/restxml"
|
||||
)
|
||||
|
||||
// Build builds the REST component of a service request.
|
||||
func Build(r *aws.Request) {
|
||||
if r.ContentType == "application/json" {
|
||||
restjson.Build(r)
|
||||
} else {
|
||||
restxml.Build(r)
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalBody unmarshal a response body for the REST protocol.
|
||||
func UnmarshalBody(r *aws.Request) {
|
||||
rest.Unmarshal(r)
|
||||
if r.ContentType == "application/json" {
|
||||
restjson.Unmarshal(r)
|
||||
} else {
|
||||
restxml.Unmarshal(r)
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalMeta unmarshal response headers for the REST protocol.
|
||||
func UnmarshalMeta(r *aws.Request) {
|
||||
rest.UnmarshalMeta(r)
|
||||
}
|
||||
|
||||
// UnmarshalError unmarshal a response error for the REST protocol.
|
||||
func UnmarshalError(r *aws.Request) {
|
||||
restxml.UnmarshalError(r)
|
||||
}
|
||||
199
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/json/jsonutil/build.go
generated
vendored
Normal file
199
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/json/jsonutil/build.go
generated
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
// Package jsonutil provides JSON serialisation of AWS requests and responses.
|
||||
package jsonutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BuildJSON builds a JSON string for a given object v.
|
||||
func BuildJSON(v interface{}) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
err := buildAny(reflect.ValueOf(v), &buf, "")
|
||||
return buf.Bytes(), err
|
||||
}
|
||||
|
||||
func buildAny(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error {
|
||||
value = reflect.Indirect(value)
|
||||
if !value.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
vtype := value.Type()
|
||||
|
||||
t := tag.Get("type")
|
||||
if t == "" {
|
||||
switch vtype.Kind() {
|
||||
case reflect.Struct:
|
||||
// also it can't be a time object
|
||||
if _, ok := value.Interface().(time.Time); !ok {
|
||||
t = "structure"
|
||||
}
|
||||
case reflect.Slice:
|
||||
// also it can't be a byte slice
|
||||
if _, ok := value.Interface().([]byte); !ok {
|
||||
t = "list"
|
||||
}
|
||||
case reflect.Map:
|
||||
t = "map"
|
||||
}
|
||||
}
|
||||
|
||||
switch t {
|
||||
case "structure":
|
||||
if field, ok := vtype.FieldByName("SDKShapeTraits"); ok {
|
||||
tag = field.Tag
|
||||
}
|
||||
return buildStruct(value, buf, tag)
|
||||
case "list":
|
||||
return buildList(value, buf, tag)
|
||||
case "map":
|
||||
return buildMap(value, buf, tag)
|
||||
default:
|
||||
return buildScalar(value, buf, tag)
|
||||
}
|
||||
}
|
||||
|
||||
func buildStruct(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error {
|
||||
if !value.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
buf.WriteString("{")
|
||||
|
||||
t, fields := value.Type(), []*reflect.StructField{}
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
member := value.FieldByName(field.Name)
|
||||
if (member.Kind() == reflect.Ptr || member.Kind() == reflect.Slice || member.Kind() == reflect.Map) && member.IsNil() {
|
||||
continue // ignore unset fields
|
||||
}
|
||||
if c := field.Name[0:1]; strings.ToLower(c) == c {
|
||||
continue // ignore unexported fields
|
||||
}
|
||||
if field.Tag.Get("location") != "" {
|
||||
continue // ignore non-body elements
|
||||
}
|
||||
|
||||
fields = append(fields, &field)
|
||||
}
|
||||
|
||||
for i, field := range fields {
|
||||
member := value.FieldByName(field.Name)
|
||||
|
||||
// figure out what this field is called
|
||||
name := field.Name
|
||||
if locName := field.Tag.Get("locationName"); locName != "" {
|
||||
name = locName
|
||||
}
|
||||
|
||||
buf.WriteString(fmt.Sprintf("%q:", name))
|
||||
|
||||
err := buildAny(member, buf, field.Tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if i < len(fields)-1 {
|
||||
buf.WriteString(",")
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString("}")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildList(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error {
|
||||
buf.WriteString("[")
|
||||
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
buildAny(value.Index(i), buf, "")
|
||||
|
||||
if i < value.Len()-1 {
|
||||
buf.WriteString(",")
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString("]")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildMap(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error {
|
||||
buf.WriteString("{")
|
||||
|
||||
keys := make([]string, value.Len())
|
||||
for i, n := range value.MapKeys() {
|
||||
keys[i] = n.String()
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
for i, k := range keys {
|
||||
buf.WriteString(fmt.Sprintf("%q:", k))
|
||||
buildAny(value.MapIndex(reflect.ValueOf(k)), buf, "")
|
||||
|
||||
if i < len(keys)-1 {
|
||||
buf.WriteString(",")
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteString("}")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildScalar(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error {
|
||||
switch converted := value.Interface().(type) {
|
||||
case string:
|
||||
writeString(converted, buf)
|
||||
case []byte:
|
||||
if !value.IsNil() {
|
||||
buf.WriteString(fmt.Sprintf("%q", base64.StdEncoding.EncodeToString(converted)))
|
||||
}
|
||||
case bool:
|
||||
buf.WriteString(strconv.FormatBool(converted))
|
||||
case int64:
|
||||
buf.WriteString(strconv.FormatInt(converted, 10))
|
||||
case float64:
|
||||
buf.WriteString(strconv.FormatFloat(converted, 'f', -1, 64))
|
||||
case time.Time:
|
||||
buf.WriteString(strconv.FormatInt(converted.UTC().Unix(), 10))
|
||||
default:
|
||||
return fmt.Errorf("unsupported JSON value %v (%s)", value.Interface(), value.Type())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeString(s string, buf *bytes.Buffer) {
|
||||
buf.WriteByte('"')
|
||||
for _, r := range s {
|
||||
if r == '"' {
|
||||
buf.WriteString(`\"`)
|
||||
} else if r == '\\' {
|
||||
buf.WriteString(`\\`)
|
||||
} else if r == '\b' {
|
||||
buf.WriteString(`\b`)
|
||||
} else if r == '\f' {
|
||||
buf.WriteString(`\f`)
|
||||
} else if r == '\r' {
|
||||
buf.WriteString(`\r`)
|
||||
} else if r == '\t' {
|
||||
buf.WriteString(`\t`)
|
||||
} else if r == '\n' {
|
||||
buf.WriteString(`\n`)
|
||||
} else if r < 32 {
|
||||
fmt.Fprintf(buf, "\\u%0.4x", r)
|
||||
} else {
|
||||
buf.WriteRune(r)
|
||||
}
|
||||
}
|
||||
buf.WriteByte('"')
|
||||
}
|
||||
214
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/json/jsonutil/unmarshal.go
generated
vendored
Normal file
214
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/json/jsonutil/unmarshal.go
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
package jsonutil
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// UnmarshalJSON reads a stream and unmarshals the results in object v.
|
||||
func UnmarshalJSON(v interface{}, stream io.Reader) error {
|
||||
var out interface{}
|
||||
|
||||
b, err := ioutil.ReadAll(stream)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(b) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(b, &out); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return unmarshalAny(reflect.ValueOf(v), out, "")
|
||||
}
|
||||
|
||||
func unmarshalAny(value reflect.Value, data interface{}, tag reflect.StructTag) error {
|
||||
vtype := value.Type()
|
||||
if vtype.Kind() == reflect.Ptr {
|
||||
vtype = vtype.Elem() // check kind of actual element type
|
||||
}
|
||||
|
||||
t := tag.Get("type")
|
||||
if t == "" {
|
||||
switch vtype.Kind() {
|
||||
case reflect.Struct:
|
||||
// also it can't be a time object
|
||||
if _, ok := value.Interface().(*time.Time); !ok {
|
||||
t = "structure"
|
||||
}
|
||||
case reflect.Slice:
|
||||
// also it can't be a byte slice
|
||||
if _, ok := value.Interface().([]byte); !ok {
|
||||
t = "list"
|
||||
}
|
||||
case reflect.Map:
|
||||
t = "map"
|
||||
}
|
||||
}
|
||||
|
||||
switch t {
|
||||
case "structure":
|
||||
if field, ok := vtype.FieldByName("SDKShapeTraits"); ok {
|
||||
tag = field.Tag
|
||||
}
|
||||
return unmarshalStruct(value, data, tag)
|
||||
case "list":
|
||||
return unmarshalList(value, data, tag)
|
||||
case "map":
|
||||
return unmarshalMap(value, data, tag)
|
||||
default:
|
||||
return unmarshalScalar(value, data, tag)
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalStruct(value reflect.Value, data interface{}, tag reflect.StructTag) error {
|
||||
if data == nil {
|
||||
return nil
|
||||
}
|
||||
mapData, ok := data.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("JSON value is not a structure (%#v)", data)
|
||||
}
|
||||
|
||||
t := value.Type()
|
||||
if value.Kind() == reflect.Ptr {
|
||||
if value.IsNil() { // create the structure if it's nil
|
||||
s := reflect.New(value.Type().Elem())
|
||||
value.Set(s)
|
||||
value = s
|
||||
}
|
||||
|
||||
value = value.Elem()
|
||||
t = t.Elem()
|
||||
}
|
||||
|
||||
// unwrap any payloads
|
||||
if payload := tag.Get("payload"); payload != "" {
|
||||
field, _ := t.FieldByName(payload)
|
||||
return unmarshalAny(value.FieldByName(payload), data, field.Tag)
|
||||
}
|
||||
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
if c := field.Name[0:1]; strings.ToLower(c) == c {
|
||||
continue // ignore unexported fields
|
||||
}
|
||||
|
||||
// figure out what this field is called
|
||||
name := field.Name
|
||||
if locName := field.Tag.Get("locationName"); locName != "" {
|
||||
name = locName
|
||||
}
|
||||
|
||||
member := value.FieldByName(field.Name)
|
||||
err := unmarshalAny(member, mapData[name], field.Tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func unmarshalList(value reflect.Value, data interface{}, tag reflect.StructTag) error {
|
||||
if data == nil {
|
||||
return nil
|
||||
}
|
||||
listData, ok := data.([]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("JSON value is not a list (%#v)", data)
|
||||
}
|
||||
|
||||
if value.IsNil() {
|
||||
l := len(listData)
|
||||
value.Set(reflect.MakeSlice(value.Type(), l, l))
|
||||
}
|
||||
|
||||
for i, c := range listData {
|
||||
err := unmarshalAny(value.Index(i), c, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func unmarshalMap(value reflect.Value, data interface{}, tag reflect.StructTag) error {
|
||||
if data == nil {
|
||||
return nil
|
||||
}
|
||||
mapData, ok := data.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("JSON value is not a map (%#v)", data)
|
||||
}
|
||||
|
||||
if value.IsNil() {
|
||||
value.Set(reflect.MakeMap(value.Type()))
|
||||
}
|
||||
|
||||
for k, v := range mapData {
|
||||
kvalue := reflect.ValueOf(k)
|
||||
vvalue := reflect.New(value.Type().Elem()).Elem()
|
||||
|
||||
unmarshalAny(vvalue, v, "")
|
||||
value.SetMapIndex(kvalue, vvalue)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTag) error {
|
||||
errf := func() error {
|
||||
return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type())
|
||||
}
|
||||
|
||||
switch d := data.(type) {
|
||||
case nil:
|
||||
return nil // nothing to do here
|
||||
case string:
|
||||
switch value.Interface().(type) {
|
||||
case *string:
|
||||
value.Set(reflect.ValueOf(&d))
|
||||
case []byte:
|
||||
b, err := base64.StdEncoding.DecodeString(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
value.Set(reflect.ValueOf(b))
|
||||
default:
|
||||
return errf()
|
||||
}
|
||||
case float64:
|
||||
switch value.Interface().(type) {
|
||||
case *int64:
|
||||
di := int64(d)
|
||||
value.Set(reflect.ValueOf(&di))
|
||||
case *float64:
|
||||
value.Set(reflect.ValueOf(&d))
|
||||
case *time.Time:
|
||||
t := time.Unix(int64(d), 0).UTC()
|
||||
value.Set(reflect.ValueOf(&t))
|
||||
default:
|
||||
return errf()
|
||||
}
|
||||
case bool:
|
||||
switch value.Interface().(type) {
|
||||
case *bool:
|
||||
value.Set(reflect.ValueOf(&d))
|
||||
default:
|
||||
return errf()
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unsupported JSON value (%v)", data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
121
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/jsonrpc/jsonrpc.go
generated
vendored
Normal file
121
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/jsonrpc/jsonrpc.go
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
// Package jsonrpc provides JSON RPC utilities for serialisation of AWS
|
||||
// requests and responses.
|
||||
package jsonrpc
|
||||
|
||||
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/input/json.json build_test.go
|
||||
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/output/json.json unmarshal_test.go
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/json/jsonutil"
|
||||
)
|
||||
|
||||
var emptyJSON = []byte("{}")
|
||||
|
||||
// Build builds a JSON payload for a JSON RPC request.
|
||||
func Build(req *aws.Request) {
|
||||
var buf []byte
|
||||
var err error
|
||||
if req.ParamsFilled() {
|
||||
v := reflect.ValueOf(req.Params).Elem()
|
||||
if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok {
|
||||
if payloadName := field.Tag.Get("payload"); payloadName != "" {
|
||||
pfield, _ := v.Type().FieldByName(payloadName)
|
||||
if ptag := pfield.Tag.Get("type"); ptag == "" || ptag == "structure" {
|
||||
payload := reflect.Indirect(v.FieldByName(payloadName))
|
||||
if payload.IsValid() && payload.Interface() != nil {
|
||||
buf, err = jsonutil.BuildJSON(payload.Interface())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
req.Error = apierr.New("Marshal", "failed encoding JSON RPC request", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
buf = emptyJSON
|
||||
}
|
||||
|
||||
if req.Service.TargetPrefix != "" || string(buf) != "{}" {
|
||||
req.SetBufferBody(buf)
|
||||
}
|
||||
|
||||
if req.Service.TargetPrefix != "" {
|
||||
target := req.Service.TargetPrefix + "." + req.Operation.Name
|
||||
req.HTTPRequest.Header.Add("X-Amz-Target", target)
|
||||
}
|
||||
if req.Service.JSONVersion != "" {
|
||||
jsonVersion := req.Service.JSONVersion
|
||||
req.HTTPRequest.Header.Add("Content-Type", "application/x-amz-json-"+jsonVersion)
|
||||
}
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals a response for a JSON RPC service.
|
||||
func Unmarshal(req *aws.Request) {
|
||||
defer req.HTTPResponse.Body.Close()
|
||||
if req.DataFilled() {
|
||||
v := reflect.ValueOf(req.Data).Elem()
|
||||
if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok {
|
||||
if payloadName := field.Tag.Get("payload"); payloadName != "" {
|
||||
pfield, _ := v.Type().FieldByName(payloadName)
|
||||
if ptag := pfield.Tag.Get("type"); ptag == "" || ptag == "structure" {
|
||||
payload := v.FieldByName(payloadName)
|
||||
if payload.IsValid() && payload.Interface() != nil {
|
||||
err := jsonutil.UnmarshalJSON(payload.Interface(), req.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
req.Error = apierr.New("Unmarshal", "failed decoding JSON RPC response", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UnmarshalMeta unmarshals headers from a response for a JSON RPC service.
|
||||
func UnmarshalMeta(req *aws.Request) {
|
||||
req.RequestID = req.HTTPResponse.Header.Get("x-amzn-requestid")
|
||||
}
|
||||
|
||||
// UnmarshalError unmarshals an error response for a JSON RPC service.
|
||||
func UnmarshalError(req *aws.Request) {
|
||||
defer req.HTTPResponse.Body.Close()
|
||||
bodyBytes, err := ioutil.ReadAll(req.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
req.Error = apierr.New("Unmarshal", "failed reading JSON RPC error response", err)
|
||||
return
|
||||
}
|
||||
if len(bodyBytes) == 0 {
|
||||
req.Error = apierr.NewRequestError(
|
||||
apierr.New("Unmarshal", req.HTTPResponse.Status, nil),
|
||||
req.HTTPResponse.StatusCode,
|
||||
"",
|
||||
)
|
||||
return
|
||||
}
|
||||
var jsonErr jsonErrorResponse
|
||||
if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil {
|
||||
req.Error = apierr.New("Unmarshal", "failed decoding JSON RPC error response", err)
|
||||
return
|
||||
}
|
||||
|
||||
codes := strings.SplitN(jsonErr.Code, "#", 2)
|
||||
req.Error = apierr.NewRequestError(
|
||||
apierr.New(codes[len(codes)-1], jsonErr.Message, nil),
|
||||
req.HTTPResponse.StatusCode,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
type jsonErrorResponse struct {
|
||||
Code string `json:"__type"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
33
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/query/build.go
generated
vendored
Normal file
33
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/query/build.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// Package query provides serialisation of AWS query requests, and responses.
|
||||
package query
|
||||
|
||||
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/input/query.json build_test.go
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/query/queryutil"
|
||||
)
|
||||
|
||||
// Build builds a request for an AWS Query service.
|
||||
func Build(r *aws.Request) {
|
||||
body := url.Values{
|
||||
"Action": {r.Operation.Name},
|
||||
"Version": {r.Service.APIVersion},
|
||||
}
|
||||
if err := queryutil.Parse(body, r.Params, false); err != nil {
|
||||
r.Error = apierr.New("Marshal", "failed encoding Query request", err)
|
||||
return
|
||||
}
|
||||
|
||||
if r.ExpireTime == 0 {
|
||||
r.HTTPRequest.Method = "POST"
|
||||
r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
|
||||
r.SetBufferBody([]byte(body.Encode()))
|
||||
} else { // This is a pre-signed request
|
||||
r.HTTPRequest.Method = "GET"
|
||||
r.HTTPRequest.URL.RawQuery = body.Encode()
|
||||
}
|
||||
}
|
||||
223
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/query/queryutil/queryutil.go
generated
vendored
Normal file
223
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/query/queryutil/queryutil.go
generated
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
package queryutil
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Parse parses an object i and fills a url.Values object. The isEC2 flag
|
||||
// indicates if this is the EC2 Query sub-protocol.
|
||||
func Parse(body url.Values, i interface{}, isEC2 bool) error {
|
||||
q := queryParser{isEC2: isEC2}
|
||||
return q.parseValue(body, reflect.ValueOf(i), "", "")
|
||||
}
|
||||
|
||||
func elemOf(value reflect.Value) reflect.Value {
|
||||
for value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
type queryParser struct {
|
||||
isEC2 bool
|
||||
}
|
||||
|
||||
func (q *queryParser) parseValue(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
|
||||
value = elemOf(value)
|
||||
|
||||
// no need to handle zero values
|
||||
if !value.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
t := tag.Get("type")
|
||||
if t == "" {
|
||||
switch value.Kind() {
|
||||
case reflect.Struct:
|
||||
t = "structure"
|
||||
case reflect.Slice:
|
||||
t = "list"
|
||||
case reflect.Map:
|
||||
t = "map"
|
||||
}
|
||||
}
|
||||
|
||||
switch t {
|
||||
case "structure":
|
||||
return q.parseStruct(v, value, prefix)
|
||||
case "list":
|
||||
return q.parseList(v, value, prefix, tag)
|
||||
case "map":
|
||||
return q.parseMap(v, value, prefix, tag)
|
||||
default:
|
||||
return q.parseScalar(v, value, prefix, tag)
|
||||
}
|
||||
}
|
||||
|
||||
func (q *queryParser) parseStruct(v url.Values, value reflect.Value, prefix string) error {
|
||||
if !value.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
t := value.Type()
|
||||
for i := 0; i < value.NumField(); i++ {
|
||||
if c := t.Field(i).Name[0:1]; strings.ToLower(c) == c {
|
||||
continue // ignore unexported fields
|
||||
}
|
||||
|
||||
value := elemOf(value.Field(i))
|
||||
field := t.Field(i)
|
||||
var name string
|
||||
|
||||
if q.isEC2 {
|
||||
name = field.Tag.Get("queryName")
|
||||
}
|
||||
if name == "" {
|
||||
if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" {
|
||||
name = field.Tag.Get("locationNameList")
|
||||
} else if locName := field.Tag.Get("locationName"); locName != "" {
|
||||
name = locName
|
||||
}
|
||||
if name != "" && q.isEC2 {
|
||||
name = strings.ToUpper(name[0:1]) + name[1:]
|
||||
}
|
||||
}
|
||||
if name == "" {
|
||||
name = field.Name
|
||||
}
|
||||
|
||||
if prefix != "" {
|
||||
name = prefix + "." + name
|
||||
}
|
||||
|
||||
if err := q.parseValue(v, value, name, field.Tag); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
|
||||
// If it's empty, generate an empty value
|
||||
if !value.IsNil() && value.Len() == 0 {
|
||||
v.Set(prefix, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
// check for unflattened list member
|
||||
if !q.isEC2 && tag.Get("flattened") == "" {
|
||||
prefix += ".member"
|
||||
}
|
||||
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
slicePrefix := prefix
|
||||
if slicePrefix == "" {
|
||||
slicePrefix = strconv.Itoa(i + 1)
|
||||
} else {
|
||||
slicePrefix = slicePrefix + "." + strconv.Itoa(i+1)
|
||||
}
|
||||
if err := q.parseValue(v, value.Index(i), slicePrefix, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *queryParser) parseMap(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
|
||||
// If it's empty, generate an empty value
|
||||
if !value.IsNil() && value.Len() == 0 {
|
||||
v.Set(prefix, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
// check for unflattened list member
|
||||
if !q.isEC2 && tag.Get("flattened") == "" {
|
||||
prefix += ".entry"
|
||||
}
|
||||
|
||||
// sort keys for improved serialization consistency.
|
||||
// this is not strictly necessary for protocol support.
|
||||
mapKeyValues := value.MapKeys()
|
||||
mapKeys := map[string]reflect.Value{}
|
||||
mapKeyNames := make([]string, len(mapKeyValues))
|
||||
for i, mapKey := range mapKeyValues {
|
||||
name := mapKey.String()
|
||||
mapKeys[name] = mapKey
|
||||
mapKeyNames[i] = name
|
||||
}
|
||||
sort.Strings(mapKeyNames)
|
||||
|
||||
for i, mapKeyName := range mapKeyNames {
|
||||
mapKey := mapKeys[mapKeyName]
|
||||
mapValue := value.MapIndex(mapKey)
|
||||
|
||||
kname := tag.Get("locationNameKey")
|
||||
if kname == "" {
|
||||
kname = "key"
|
||||
}
|
||||
vname := tag.Get("locationNameValue")
|
||||
if vname == "" {
|
||||
vname = "value"
|
||||
}
|
||||
|
||||
// serialize key
|
||||
var keyName string
|
||||
if prefix == "" {
|
||||
keyName = strconv.Itoa(i+1) + "." + kname
|
||||
} else {
|
||||
keyName = prefix + "." + strconv.Itoa(i+1) + "." + kname
|
||||
}
|
||||
|
||||
if err := q.parseValue(v, mapKey, keyName, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// serialize value
|
||||
var valueName string
|
||||
if prefix == "" {
|
||||
valueName = strconv.Itoa(i+1) + "." + vname
|
||||
} else {
|
||||
valueName = prefix + "." + strconv.Itoa(i+1) + "." + vname
|
||||
}
|
||||
|
||||
if err := q.parseValue(v, mapValue, valueName, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, tag reflect.StructTag) error {
|
||||
switch value := r.Interface().(type) {
|
||||
case string:
|
||||
v.Set(name, value)
|
||||
case []byte:
|
||||
if !r.IsNil() {
|
||||
v.Set(name, base64.StdEncoding.EncodeToString(value))
|
||||
}
|
||||
case bool:
|
||||
v.Set(name, strconv.FormatBool(value))
|
||||
case int64:
|
||||
v.Set(name, strconv.FormatInt(value, 10))
|
||||
case int:
|
||||
v.Set(name, strconv.Itoa(value))
|
||||
case float64:
|
||||
v.Set(name, strconv.FormatFloat(value, 'f', -1, 64))
|
||||
case float32:
|
||||
v.Set(name, strconv.FormatFloat(float64(value), 'f', -1, 32))
|
||||
case time.Time:
|
||||
const ISO8601UTC = "2006-01-02T15:04:05Z"
|
||||
v.Set(name, value.UTC().Format(ISO8601UTC))
|
||||
default:
|
||||
return fmt.Errorf("unsupported value for param %s: %v (%s)", name, r.Interface(), r.Type().Name())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
29
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/query/unmarshal.go
generated
vendored
Normal file
29
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/query/unmarshal.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
package query
|
||||
|
||||
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/output/query.json unmarshal_test.go
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/xml/xmlutil"
|
||||
)
|
||||
|
||||
// Unmarshal unmarshals a response for an AWS Query service.
|
||||
func Unmarshal(r *aws.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
if r.DataFilled() {
|
||||
decoder := xml.NewDecoder(r.HTTPResponse.Body)
|
||||
err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result")
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Unmarshal", "failed decoding Query response", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalMeta unmarshals header response values for an AWS Query service.
|
||||
func UnmarshalMeta(r *aws.Request) {
|
||||
// TODO implement unmarshaling of request IDs
|
||||
}
|
||||
108
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/query/unmarshal_error.go
generated
vendored
Normal file
108
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/query/unmarshal_error.go
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type XmlErrorResponse struct {
|
||||
XMLName xml.Name `xml:"Error"`
|
||||
Code string `xml:"Code"`
|
||||
StatusCode int `xml:"StatusCode"`
|
||||
Message string `xml:"Message"`
|
||||
Resource string `xml:"Resource"`
|
||||
RequestID string `xml:"RequestId"`
|
||||
}
|
||||
|
||||
type Ks3BillJsonErrorResponse struct {
|
||||
XMLName xml.Name `xml:"Error"`
|
||||
Code string `xml:"Code"`
|
||||
Message string `xml:"Message"`
|
||||
RequestID string `xml:"RequestId"`
|
||||
}
|
||||
|
||||
type Ks3BillXmlErrorResponse struct {
|
||||
XMLName xml.Name `xml:"ErrorResponse"`
|
||||
RequestID string `xml:"RequestId"`
|
||||
Error Ks3BillXmlError `xml:"Error"`
|
||||
}
|
||||
|
||||
type Ks3BillXmlError struct {
|
||||
XMLName xml.Name `xml:"Error"`
|
||||
Code string `xml:"Code"`
|
||||
Message string `xml:"Message"`
|
||||
}
|
||||
|
||||
// UnmarshalError unmarshal an error response for an AWS Query service.
|
||||
func UnmarshalError(r *aws.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Unmarshal", "failed to read body", err)
|
||||
return
|
||||
}
|
||||
|
||||
if r.RequestType == "ks3bill" {
|
||||
if strings.Contains(r.HTTPResponse.Header.Get("Content-Type"), "application/xml") {
|
||||
resp := &Ks3BillXmlErrorResponse{}
|
||||
err = xml.Unmarshal(body, &resp)
|
||||
if err != nil && err != io.EOF {
|
||||
r.Error = apierr.New("Unmarshal", "failed to decode ks3bill xml error response", err)
|
||||
return
|
||||
}
|
||||
|
||||
r.Error = apierr.NewRequestError(apierr.New(resp.Error.Code, resp.Error.Message, nil), r.HTTPResponse.StatusCode, resp.RequestID)
|
||||
return
|
||||
}
|
||||
|
||||
resp := &Ks3BillJsonErrorResponse{}
|
||||
err = json.Unmarshal(body, &resp)
|
||||
if err != nil && err != io.EOF {
|
||||
r.Error = apierr.New("Unmarshal", "failed to decode ks3bill json error response", err)
|
||||
return
|
||||
}
|
||||
|
||||
r.Error = apierr.NewRequestError(apierr.New(resp.Code, resp.Message, nil), r.HTTPResponse.StatusCode, resp.RequestID)
|
||||
return
|
||||
}
|
||||
|
||||
resp := &XmlErrorResponse{}
|
||||
// 如果响应类型是html,则解析html文本
|
||||
if strings.Contains(r.HTTPResponse.Header.Get("Content-Type"), "text/html") {
|
||||
// 获取HTML文本中title标签的内容
|
||||
re := regexp.MustCompile(`<title>(.*?)</title>`)
|
||||
matches := re.FindStringSubmatch(string(body))
|
||||
|
||||
title := ""
|
||||
if len(matches) > 1 {
|
||||
title = matches[1]
|
||||
}
|
||||
|
||||
r.Error = apierr.NewRequestError(apierr.New(title, "", nil), r.HTTPResponse.StatusCode, "")
|
||||
return
|
||||
}
|
||||
|
||||
err = xml.Unmarshal(body, &resp)
|
||||
resp.StatusCode = r.HTTPResponse.StatusCode
|
||||
|
||||
// head请求无法从body中获取request id,如果是head请求,则从header中获取
|
||||
if resp.RequestID == "" && r.HTTPRequest.Method == "HEAD" {
|
||||
resp.RequestID = r.HTTPResponse.Header.Get("X-Kss-Request-Id")
|
||||
}
|
||||
|
||||
if err != nil && err != io.EOF {
|
||||
r.Error = apierr.New("Unmarshal", "failed to decode query XML error response", err)
|
||||
} else {
|
||||
r.Error = apierr.NewRequestError(
|
||||
apierr.New(resp.Code, resp.Message, nil),
|
||||
r.HTTPResponse.StatusCode,
|
||||
resp.RequestID,
|
||||
)
|
||||
}
|
||||
}
|
||||
397
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/rest/build.go
generated
vendored
Normal file
397
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/rest/build.go
generated
vendored
Normal file
@@ -0,0 +1,397 @@
|
||||
// Package rest provides RESTful serialisation of AWS requests and responses.
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
"io"
|
||||
"net/url"
|
||||
"path"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RFC822 returns an RFC822 formatted timestamp for AWS protocols
|
||||
const RFC822 = "Mon, 2 Jan 2006 15:04:05 GMT"
|
||||
|
||||
// Whether the byte value can be sent without escaping in AWS URLs
|
||||
var noEscape [256]bool
|
||||
|
||||
func init() {
|
||||
for i := 0; i < len(noEscape); i++ {
|
||||
// AWS expects every character except these to be escaped
|
||||
noEscape[i] = (i >= 'A' && i <= 'Z') ||
|
||||
(i >= 'a' && i <= 'z') ||
|
||||
(i >= '0' && i <= '9') ||
|
||||
i == '-' ||
|
||||
i == '.' ||
|
||||
i == '_' ||
|
||||
i == '~'
|
||||
}
|
||||
}
|
||||
|
||||
var isTokenTable = [256]bool{
|
||||
'!': true,
|
||||
'#': true,
|
||||
'$': true,
|
||||
'%': true,
|
||||
'&': true,
|
||||
'\'': true,
|
||||
'*': true,
|
||||
'+': true,
|
||||
'-': true,
|
||||
'.': true,
|
||||
'0': true,
|
||||
'1': true,
|
||||
'2': true,
|
||||
'3': true,
|
||||
'4': true,
|
||||
'5': true,
|
||||
'6': true,
|
||||
'7': true,
|
||||
'8': true,
|
||||
'9': true,
|
||||
'A': true,
|
||||
'B': true,
|
||||
'C': true,
|
||||
'D': true,
|
||||
'E': true,
|
||||
'F': true,
|
||||
'G': true,
|
||||
'H': true,
|
||||
'I': true,
|
||||
'J': true,
|
||||
'K': true,
|
||||
'L': true,
|
||||
'M': true,
|
||||
'N': true,
|
||||
'O': true,
|
||||
'P': true,
|
||||
'Q': true,
|
||||
'R': true,
|
||||
'S': true,
|
||||
'T': true,
|
||||
'U': true,
|
||||
'W': true,
|
||||
'V': true,
|
||||
'X': true,
|
||||
'Y': true,
|
||||
'Z': true,
|
||||
'^': true,
|
||||
'_': true,
|
||||
'`': true,
|
||||
'a': true,
|
||||
'b': true,
|
||||
'c': true,
|
||||
'd': true,
|
||||
'e': true,
|
||||
'f': true,
|
||||
'g': true,
|
||||
'h': true,
|
||||
'i': true,
|
||||
'j': true,
|
||||
'k': true,
|
||||
'l': true,
|
||||
'm': true,
|
||||
'n': true,
|
||||
'o': true,
|
||||
'p': true,
|
||||
'q': true,
|
||||
'r': true,
|
||||
's': true,
|
||||
't': true,
|
||||
'u': true,
|
||||
'v': true,
|
||||
'w': true,
|
||||
'x': true,
|
||||
'y': true,
|
||||
'z': true,
|
||||
'|': true,
|
||||
'~': true,
|
||||
}
|
||||
|
||||
func ValidHeaderFieldName(v string) bool {
|
||||
if len(v) == 0 {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(v); i++ {
|
||||
if !isTokenTable[v[i]] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Build builds the REST component of a service request.
|
||||
func Build(r *aws.Request) {
|
||||
if r.ParamsFilled() {
|
||||
v := reflect.ValueOf(r.Params).Elem()
|
||||
buildLocationElements(r, v)
|
||||
buildBody(r, v)
|
||||
}
|
||||
}
|
||||
|
||||
func buildLocationElements(r *aws.Request, v reflect.Value) {
|
||||
query := r.HTTPRequest.URL.Query()
|
||||
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
m := v.Field(i)
|
||||
if n := v.Type().Field(i).Name; n[0:1] == strings.ToLower(n[0:1]) {
|
||||
continue
|
||||
}
|
||||
|
||||
if m.IsValid() {
|
||||
field := v.Type().Field(i)
|
||||
name := field.Tag.Get("locationName")
|
||||
if name == "" {
|
||||
name = field.Name
|
||||
}
|
||||
if m.Kind() == reflect.Ptr {
|
||||
m = m.Elem()
|
||||
}
|
||||
if !m.IsValid() {
|
||||
continue
|
||||
}
|
||||
|
||||
switch field.Tag.Get("location") {
|
||||
case "headers": // header maps
|
||||
buildHeaderMap(r, m, field.Tag.Get("locationName"))
|
||||
case "header":
|
||||
buildHeader(r, m, name)
|
||||
case "uri":
|
||||
buildURI(r, m, name)
|
||||
case "querystring":
|
||||
buildQueryString(r, m, name, query)
|
||||
case "querystrings":
|
||||
buildQueryStrings(r, m, name, query)
|
||||
}
|
||||
}
|
||||
if r.Error != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
buildExtendHeaders(r, v)
|
||||
buildExtendQueryParams(v, query)
|
||||
|
||||
r.HTTPRequest.URL.RawQuery = query.Encode()
|
||||
updatePath(r.HTTPRequest.URL, r.Config)
|
||||
}
|
||||
|
||||
func buildBody(r *aws.Request, v reflect.Value) {
|
||||
if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok {
|
||||
if payloadName := field.Tag.Get("payload"); payloadName != "" {
|
||||
pfield, _ := v.Type().FieldByName(payloadName)
|
||||
if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" {
|
||||
payload := reflect.Indirect(v.FieldByName(payloadName))
|
||||
if payload.IsValid() && payload.Interface() != nil {
|
||||
switch reader := payload.Interface().(type) {
|
||||
case io.ReadSeeker:
|
||||
r.SetReaderBody(reader)
|
||||
case []byte:
|
||||
r.SetBufferBody(reader)
|
||||
case string:
|
||||
r.SetStringBody(reader)
|
||||
default:
|
||||
r.Error = apierr.New("Marshal",
|
||||
"failed to encode REST request",
|
||||
fmt.Errorf("unknown payload type %s", payload.Type()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildHeader(r *aws.Request, v reflect.Value, name string) {
|
||||
str, err := convertType(v)
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Marshal", "failed to encode REST request", err)
|
||||
} else if str != nil {
|
||||
r.HTTPRequest.Header.Add(name, *str)
|
||||
}
|
||||
}
|
||||
|
||||
func buildHeaderMap(r *aws.Request, v reflect.Value, prefix string) {
|
||||
for _, key := range v.MapKeys() {
|
||||
str, err := convertType(v.MapIndex(key))
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Marshal", "failed to encode REST request", err)
|
||||
} else if str != nil {
|
||||
if strings.HasPrefix(strings.ToLower(key.String()), strings.ToLower(prefix)) {
|
||||
r.HTTPRequest.Header.Add(key.String(), *str)
|
||||
} else {
|
||||
r.HTTPRequest.Header.Add(prefix+key.String(), *str)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildExtendHeaders(r *aws.Request, v reflect.Value) {
|
||||
extendHeaders := v.FieldByName("ExtendHeaders")
|
||||
if extendHeaders.IsValid() {
|
||||
iter := extendHeaders.MapRange()
|
||||
for iter.Next() {
|
||||
key := iter.Key().String()
|
||||
value := iter.Value()
|
||||
if ValidHeaderFieldName(key) {
|
||||
if !value.IsNil() {
|
||||
r.HTTPRequest.Header.Set(key, value.Elem().String())
|
||||
} else {
|
||||
r.HTTPRequest.Header.Set(key, "")
|
||||
}
|
||||
} else {
|
||||
r.Error = apierr.New("Marshal", fmt.Sprintf("invalid extend header field name \"%s\"", key), nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildExtendQueryParams(v reflect.Value, query url.Values) {
|
||||
extendQueryParams := v.FieldByName("ExtendQueryParams")
|
||||
if extendQueryParams.IsValid() {
|
||||
iter := extendQueryParams.MapRange()
|
||||
for iter.Next() {
|
||||
key := iter.Key().String()
|
||||
if key == "" {
|
||||
continue
|
||||
}
|
||||
value := iter.Value()
|
||||
if !value.IsNil() {
|
||||
query.Set(key, value.Elem().String())
|
||||
} else {
|
||||
query.Set(key, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildURI(r *aws.Request, v reflect.Value, name string) {
|
||||
value, err := convertType(v)
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Marshal", "failed to encode REST request", err)
|
||||
} else if value != nil {
|
||||
uri := r.HTTPRequest.URL.Path
|
||||
uri = strings.Replace(uri, "{"+name+"}", EscapePath(*value, true), -1)
|
||||
uri = strings.Replace(uri, "{"+name+"+}", EscapePath(*value, false), -1)
|
||||
r.HTTPRequest.URL.Path = uri
|
||||
}
|
||||
}
|
||||
|
||||
func buildQueryString(r *aws.Request, v reflect.Value, name string, query url.Values) {
|
||||
str, err := convertType(v)
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Marshal", "failed to encode REST request", err)
|
||||
} else if str != nil {
|
||||
query.Set(name, *str)
|
||||
} else if str == nil {
|
||||
query.Set(name, "")
|
||||
}
|
||||
}
|
||||
|
||||
func buildQueryStrings(r *aws.Request, v reflect.Value, name string, query url.Values) {
|
||||
if v.Kind() == reflect.Slice {
|
||||
var valSlice []string
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
str, err := convertType(v.Index(i))
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Marshal", "failed to encode REST request", err)
|
||||
return
|
||||
}
|
||||
valSlice = append(valSlice, *str)
|
||||
}
|
||||
if len(valSlice) > 0 {
|
||||
query.Set(name, strings.Join(valSlice, ","))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updatePath(url *url.URL, cfg *aws.Config) {
|
||||
urlPath := url.Path
|
||||
scheme, query := url.Scheme, url.RawQuery
|
||||
|
||||
// path.Clean will remove duplicate leading /
|
||||
// this will make deleting / started key impossible
|
||||
// so escape it here first
|
||||
urlPath = strings.Replace(urlPath, "//", "/%2F", -1)
|
||||
|
||||
// 新增参数控制path clean,默认值为true
|
||||
if !cfg.DisableRestProtocolURICleaning {
|
||||
urlPath = cleanPath(urlPath)
|
||||
}
|
||||
|
||||
// get formatted URL minus scheme, so we can build this into Opaque
|
||||
url.Scheme, url.Path, url.RawQuery = "", "", ""
|
||||
s := url.String()
|
||||
url.Scheme = scheme
|
||||
url.RawQuery = query
|
||||
|
||||
// build opaque URI
|
||||
url.Opaque = s + urlPath
|
||||
}
|
||||
|
||||
func cleanPath(urlPath string) string {
|
||||
// path.Clean会去掉最后的斜杠,导致无法创建目录。所以添加以下逻辑
|
||||
add := false
|
||||
if urlPath[len(urlPath)-1] == '/' && len(urlPath) > 1 {
|
||||
add = true
|
||||
}
|
||||
|
||||
// clean up path
|
||||
urlPath = path.Clean(urlPath)
|
||||
if add {
|
||||
urlPath += "/"
|
||||
}
|
||||
|
||||
return urlPath
|
||||
}
|
||||
|
||||
// EscapePath escapes part of a URL path in Amazon style
|
||||
//
|
||||
// path The path segment to escape
|
||||
// encodeSep If true, '/' will be encoded, otherwise they will not
|
||||
func EscapePath(path string, encodeSep bool) string {
|
||||
var buf bytes.Buffer
|
||||
for i := 0; i < len(path); i++ {
|
||||
c := path[i]
|
||||
if noEscape[c] || (c == '/' && !encodeSep) {
|
||||
buf.WriteByte(c)
|
||||
} else {
|
||||
fmt.Fprintf(&buf, "%%%02X", c)
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func convertType(v reflect.Value) (*string, error) {
|
||||
v = reflect.Indirect(v)
|
||||
if !v.IsValid() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var str string
|
||||
switch value := v.Interface().(type) {
|
||||
case string:
|
||||
str = value
|
||||
case []byte:
|
||||
str = base64.StdEncoding.EncodeToString(value)
|
||||
case bool:
|
||||
str = strconv.FormatBool(value)
|
||||
case int64:
|
||||
str = strconv.FormatInt(value, 10)
|
||||
case float64:
|
||||
str = strconv.FormatFloat(value, 'f', -1, 64)
|
||||
case time.Time:
|
||||
str = value.UTC().Format(RFC822)
|
||||
default:
|
||||
err := fmt.Errorf("unsupported value for param %v (%s)", v.Interface(), v.Type())
|
||||
return nil, err
|
||||
}
|
||||
return &str, nil
|
||||
}
|
||||
63
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/rest/payload.go
generated
vendored
Normal file
63
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/rest/payload.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// PayloadMember returns the payload field member of i if there is one, or nil.
|
||||
func PayloadMember(i interface{}) interface{} {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := reflect.ValueOf(i).Elem()
|
||||
if !v.IsValid() {
|
||||
return nil
|
||||
}
|
||||
if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok {
|
||||
if payloadName := field.Tag.Get("payload"); payloadName != "" {
|
||||
field, _ := v.Type().FieldByName(payloadName)
|
||||
if field.Tag.Get("type") != "structure" {
|
||||
return nil
|
||||
}
|
||||
|
||||
payload := v.FieldByName(payloadName)
|
||||
if payload.IsValid() || (payload.Kind() == reflect.Ptr && !payload.IsNil()) {
|
||||
return payload.Interface()
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PayloadType returns the type of a payload field member of i if there is one, or "".
|
||||
func PayloadType(i interface{}) string {
|
||||
v := reflect.Indirect(reflect.ValueOf(i))
|
||||
if !v.IsValid() {
|
||||
return ""
|
||||
}
|
||||
if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok {
|
||||
if payloadName := field.Tag.Get("payload"); payloadName != "" {
|
||||
if payloadName == "GetBucketCORSInput" {
|
||||
return field.Tag.Get("type")
|
||||
}
|
||||
if member, ok := v.Type().FieldByName(payloadName); ok {
|
||||
return member.Tag.Get("type")
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// PayloadMd5 判断给定结构体 i 中是否有 AutoFillMD5 字段
|
||||
func PayloadMd5(i interface{}) (hasField bool) {
|
||||
// 获取结构体指针的 Value
|
||||
v := reflect.Indirect(reflect.ValueOf(i))
|
||||
// 如果结构体不存在或为空,则直接返回 false
|
||||
if !v.IsValid() {
|
||||
return
|
||||
}
|
||||
// 判断是否存在 AutoFillMD5 字段
|
||||
_, hasField = v.Type().FieldByName("AutoFillMD5")
|
||||
return
|
||||
}
|
||||
180
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/rest/unmarshal.go
generated
vendored
Normal file
180
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/rest/unmarshal.go
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
)
|
||||
|
||||
// Unmarshal unmarshals the REST component of a response in a REST service.
|
||||
func Unmarshal(r *aws.Request) {
|
||||
if r.DataFilled() {
|
||||
v := reflect.Indirect(reflect.ValueOf(r.Data))
|
||||
unmarshalBody(r, v)
|
||||
}
|
||||
}
|
||||
|
||||
func UnmarshalMeta(r *aws.Request) {
|
||||
if r.DataFilled() {
|
||||
v := reflect.Indirect(reflect.ValueOf(r.Data))
|
||||
unmarshalLocationElements(r, v)
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalBody(r *aws.Request, v reflect.Value) {
|
||||
if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok {
|
||||
if payloadName := field.Tag.Get("payload"); payloadName != "" {
|
||||
pfield, _ := v.Type().FieldByName(payloadName)
|
||||
if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" {
|
||||
payload := v.FieldByName(payloadName)
|
||||
if payload.IsValid() {
|
||||
switch payload.Interface().(type) {
|
||||
case []byte:
|
||||
b, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Unmarshal", "failed to decode REST response", err)
|
||||
} else {
|
||||
payload.Set(reflect.ValueOf(b))
|
||||
}
|
||||
case *string:
|
||||
b, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Unmarshal", "failed to decode REST response", err)
|
||||
} else {
|
||||
str := string(b)
|
||||
payload.Set(reflect.ValueOf(&str))
|
||||
}
|
||||
default:
|
||||
switch payload.Type().String() {
|
||||
case "io.ReadSeeker":
|
||||
payload.Set(reflect.ValueOf(aws.ReadSeekCloser(r.HTTPResponse.Body)))
|
||||
case "aws.ReadSeekCloser", "io.ReadCloser":
|
||||
payload.Set(reflect.ValueOf(r.HTTPResponse.Body))
|
||||
default:
|
||||
r.Error = apierr.New("Unmarshal",
|
||||
"failed to decode REST response",
|
||||
fmt.Errorf("unknown payload type %s", payload.Type()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalLocationElements(r *aws.Request, v reflect.Value) {
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
m, field := v.Field(i), v.Type().Field(i)
|
||||
if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) {
|
||||
continue
|
||||
}
|
||||
|
||||
if m.IsValid() {
|
||||
name := field.Tag.Get("locationName")
|
||||
if name == "" {
|
||||
name = field.Name
|
||||
}
|
||||
|
||||
switch field.Tag.Get("location") {
|
||||
case "statusCode":
|
||||
unmarshalStatusCode(m, r.HTTPResponse.StatusCode)
|
||||
case "header":
|
||||
err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name))
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Unmarshal", "failed to decode REST response", err)
|
||||
break
|
||||
}
|
||||
case "headers":
|
||||
prefix := field.Tag.Get("locationName")
|
||||
err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix)
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Unmarshal", "failed to decode REST response", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if r.Error != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalStatusCode(v reflect.Value, statusCode int) {
|
||||
if !v.IsValid() {
|
||||
return
|
||||
}
|
||||
|
||||
switch v.Interface().(type) {
|
||||
case *int64:
|
||||
s := int64(statusCode)
|
||||
v.Set(reflect.ValueOf(&s))
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalHeaderMap(r reflect.Value, headers http.Header, prefix string) error {
|
||||
switch r.Interface().(type) {
|
||||
case map[string]*string: // we only support string map value types
|
||||
out := map[string]*string{}
|
||||
for k, v := range headers {
|
||||
k = http.CanonicalHeaderKey(k)
|
||||
if strings.HasPrefix(strings.ToLower(k), strings.ToLower(prefix)) {
|
||||
out[k[len(prefix):]] = &v[0]
|
||||
}
|
||||
}
|
||||
r.Set(reflect.ValueOf(out))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func unmarshalHeader(v reflect.Value, header string) error {
|
||||
if !v.IsValid() || (header == "" && v.Elem().Kind() != reflect.String) {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch v.Interface().(type) {
|
||||
case *string:
|
||||
v.Set(reflect.ValueOf(&header))
|
||||
case []byte:
|
||||
b, err := base64.StdEncoding.DecodeString(header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Set(reflect.ValueOf(&b))
|
||||
case *bool:
|
||||
b, err := strconv.ParseBool(header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Set(reflect.ValueOf(&b))
|
||||
case *int64:
|
||||
i, err := strconv.ParseInt(header, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Set(reflect.ValueOf(&i))
|
||||
case *float64:
|
||||
f, err := strconv.ParseFloat(header, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Set(reflect.ValueOf(&f))
|
||||
case *time.Time:
|
||||
t, err := time.Parse(RFC822, header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Set(reflect.ValueOf(&t))
|
||||
default:
|
||||
err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
77
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/restjson/restjson.go
generated
vendored
Normal file
77
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/restjson/restjson.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// Package restjson provides RESTful JSON serialisation of AWS
|
||||
// requests and responses.
|
||||
package restjson
|
||||
|
||||
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/input/rest-json.json build_test.go
|
||||
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/output/rest-json.json unmarshal_test.go
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/jsonrpc"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/rest"
|
||||
)
|
||||
|
||||
// Build builds a request for the REST JSON protocol.
|
||||
func Build(r *aws.Request) {
|
||||
rest.Build(r)
|
||||
|
||||
if t := rest.PayloadType(r.Params); t == "structure" || t == "" {
|
||||
jsonrpc.Build(r)
|
||||
}
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals a response body for the REST JSON protocol.
|
||||
func Unmarshal(r *aws.Request) {
|
||||
if t := rest.PayloadType(r.Data); t == "structure" || t == "" {
|
||||
jsonrpc.Unmarshal(r)
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalMeta unmarshals response headers for the REST JSON protocol.
|
||||
func UnmarshalMeta(r *aws.Request) {
|
||||
rest.Unmarshal(r)
|
||||
}
|
||||
|
||||
// UnmarshalError unmarshals a response error for the REST JSON protocol.
|
||||
func UnmarshalError(r *aws.Request) {
|
||||
code := r.HTTPResponse.Header.Get("X-Amzn-Errortype")
|
||||
bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Unmarshal", "failed reading REST JSON error response", err)
|
||||
return
|
||||
}
|
||||
if len(bodyBytes) == 0 {
|
||||
r.Error = apierr.NewRequestError(
|
||||
apierr.New("Unmarshal", r.HTTPResponse.Status, nil),
|
||||
r.HTTPResponse.StatusCode,
|
||||
"",
|
||||
)
|
||||
return
|
||||
}
|
||||
var jsonErr jsonErrorResponse
|
||||
if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil {
|
||||
r.Error = apierr.New("Unmarshal", "failed decoding REST JSON error response", err)
|
||||
return
|
||||
}
|
||||
|
||||
if code == "" {
|
||||
code = jsonErr.Code
|
||||
}
|
||||
|
||||
codes := strings.SplitN(code, ":", 2)
|
||||
r.Error = apierr.NewRequestError(
|
||||
apierr.New(codes[0], jsonErr.Message, nil),
|
||||
r.HTTPResponse.StatusCode,
|
||||
"",
|
||||
)
|
||||
}
|
||||
|
||||
type jsonErrorResponse struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
66
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/restxml/restxml.go
generated
vendored
Normal file
66
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/restxml/restxml.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
// Package restxml provides RESTful XML serialisation of AWS
|
||||
// requests and responses.
|
||||
package restxml
|
||||
|
||||
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/input/rest-xml.json build_test.go
|
||||
//go:generate go run ../../fixtures/protocol/generate.go ../../fixtures/protocol/output/rest-xml.json unmarshal_test.go
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/awsutil"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/query"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/rest"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/xml/xmlutil"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// Build builds a request payload for the REST XML protocol.
|
||||
func Build(r *aws.Request) {
|
||||
rest.Build(r)
|
||||
|
||||
if t := rest.PayloadType(r.Params); t == "structure" || t == "" {
|
||||
var buf bytes.Buffer
|
||||
err := xmlutil.BuildXML(r.Params, xml.NewEncoder(&buf))
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Marshal", "failed to encode rest XML request", err)
|
||||
return
|
||||
}
|
||||
r.SetBufferBody(buf.Bytes())
|
||||
if rest.PayloadMd5(r.Params) {
|
||||
//增加md5
|
||||
r.HTTPRequest.Header.Set("Content-MD5", awsutil.EncodeAsString(awsutil.ComputeMD5Hash(buf.Bytes())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals a payload response for the REST XML protocol.
|
||||
func Unmarshal(r *aws.Request) {
|
||||
if t := rest.PayloadType(r.Data); t == "structure" || t == "" {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
data, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = apierr.New("ReadBody", "failed to read response body", err)
|
||||
return
|
||||
}
|
||||
decoder := xml.NewDecoder(bytes.NewReader(data))
|
||||
err = xmlutil.UnmarshalXML(r.Data, decoder, "")
|
||||
if err != nil {
|
||||
r.Error = apierr.New("Unmarshal", "failed to decode REST XML response", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalMeta unmarshals response headers for the REST XML protocol.
|
||||
func UnmarshalMeta(r *aws.Request) {
|
||||
rest.Unmarshal(r)
|
||||
}
|
||||
|
||||
// UnmarshalError unmarshals a response error for the REST XML protocol.
|
||||
func UnmarshalError(r *aws.Request) {
|
||||
query.UnmarshalError(r)
|
||||
}
|
||||
287
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/xml/xmlutil/build.go
generated
vendored
Normal file
287
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/xml/xmlutil/build.go
generated
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
// Package xmlutil provides XML serialisation of AWS requests and responses.
|
||||
package xmlutil
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BuildXML will serialize params into an xml.Encoder.
|
||||
// Error will be returned if the serialization of any of the params or nested values fails.
|
||||
func BuildXML(params interface{}, e *xml.Encoder) error {
|
||||
b := xmlBuilder{encoder: e, namespaces: map[string]string{}}
|
||||
root := NewXMLElement(xml.Name{})
|
||||
if err := b.buildValue(reflect.ValueOf(params), root, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, c := range root.Children {
|
||||
for _, v := range c {
|
||||
return StructToXML(e, v, false)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Returns the reflection element of a value, if it is a pointer.
|
||||
func elemOf(value reflect.Value) reflect.Value {
|
||||
for value.Kind() == reflect.Ptr {
|
||||
value = value.Elem()
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// A xmlBuilder serializes values from Go code to XML
|
||||
type xmlBuilder struct {
|
||||
encoder *xml.Encoder
|
||||
namespaces map[string]string
|
||||
}
|
||||
|
||||
// buildValue generic XMLNode builder for any type. Will build value for their specific type
|
||||
// struct, list, map, scalar.
|
||||
//
|
||||
// Also takes a "type" tag value to set what type a value should be converted to XMLNode as. If
|
||||
// type is not provided reflect will be used to determine the value's type.
|
||||
func (b *xmlBuilder) buildValue(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
|
||||
value = elemOf(value)
|
||||
if !value.IsValid() { // no need to handle zero values
|
||||
return nil
|
||||
} else if tag.Get("location") != "" { // don't handle non-body location values
|
||||
return nil
|
||||
}
|
||||
|
||||
t := tag.Get("type")
|
||||
if t == "" {
|
||||
switch value.Kind() {
|
||||
case reflect.Struct:
|
||||
t = "structure"
|
||||
case reflect.Slice:
|
||||
t = "list"
|
||||
case reflect.Map:
|
||||
t = "map"
|
||||
}
|
||||
}
|
||||
|
||||
switch t {
|
||||
case "structure":
|
||||
if field, ok := value.Type().FieldByName("SDKShapeTraits"); ok {
|
||||
tag = tag + reflect.StructTag(" ") + field.Tag
|
||||
}
|
||||
return b.buildStruct(value, current, tag)
|
||||
case "list":
|
||||
return b.buildList(value, current, tag)
|
||||
case "map":
|
||||
return b.buildMap(value, current, tag)
|
||||
default:
|
||||
return b.buildScalar(value, current, tag)
|
||||
}
|
||||
}
|
||||
|
||||
// buildStruct adds a struct and its fields to the current XMLNode. All fields any any nested
|
||||
// types are converted to XMLNodes also.
|
||||
func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
|
||||
if !value.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
fieldAdded := false
|
||||
|
||||
// unwrap payloads
|
||||
if payload := tag.Get("payload"); payload != "" {
|
||||
field, _ := value.Type().FieldByName(payload)
|
||||
tag = field.Tag
|
||||
value = elemOf(value.FieldByName(payload))
|
||||
|
||||
if !value.IsValid() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
child := NewXMLElement(xml.Name{Local: tag.Get("locationName")})
|
||||
|
||||
// there is an xmlNamespace associated with this struct
|
||||
if prefix, uri := tag.Get("xmlPrefix"), tag.Get("xmlURI"); uri != "" {
|
||||
ns := xml.Attr{
|
||||
Name: xml.Name{Local: "xmlns"},
|
||||
Value: uri,
|
||||
}
|
||||
if prefix != "" {
|
||||
b.namespaces[prefix] = uri // register the namespace
|
||||
ns.Name.Local = "xmlns:" + prefix
|
||||
}
|
||||
|
||||
child.Attr = append(child.Attr, ns)
|
||||
}
|
||||
|
||||
t := value.Type()
|
||||
for i := 0; i < value.NumField(); i++ {
|
||||
if c := t.Field(i).Name[0:1]; strings.ToLower(c) == c {
|
||||
continue // ignore unexported fields
|
||||
}
|
||||
|
||||
member := elemOf(value.Field(i))
|
||||
field := t.Field(i)
|
||||
mTag := field.Tag
|
||||
|
||||
if mTag.Get("location") != "" { // skip non-body members
|
||||
continue
|
||||
}
|
||||
|
||||
memberName := mTag.Get("locationName")
|
||||
if memberName == "" {
|
||||
memberName = field.Name
|
||||
mTag = reflect.StructTag(string(mTag) + ` locationName:"` + memberName + `"`)
|
||||
}
|
||||
if err := b.buildValue(member, child, mTag); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fieldAdded = true
|
||||
}
|
||||
|
||||
if fieldAdded { // only append this child if we have one ore more valid members
|
||||
current.AddChild(child)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// buildList adds the value's list items to the current XMLNode as children nodes. All
|
||||
// nested values in the list are converted to XMLNodes also.
|
||||
func (b *xmlBuilder) buildList(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
|
||||
if value.IsNil() { // don't build omitted lists
|
||||
return nil
|
||||
}
|
||||
|
||||
// check for unflattened list member
|
||||
flattened := tag.Get("flattened") != ""
|
||||
|
||||
xname := xml.Name{Local: tag.Get("locationName")}
|
||||
if flattened {
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
child := NewXMLElement(xname)
|
||||
current.AddChild(child)
|
||||
if err := b.buildValue(value.Index(i), child, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
list := NewXMLElement(xname)
|
||||
current.AddChild(list)
|
||||
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
iname := tag.Get("locationNameList")
|
||||
if iname == "" {
|
||||
iname = "member"
|
||||
}
|
||||
|
||||
child := NewXMLElement(xml.Name{Local: iname})
|
||||
list.AddChild(child)
|
||||
if err := b.buildValue(value.Index(i), child, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// buildMap adds the value's key/value pairs to the current XMLNode as children nodes. All
|
||||
// nested values in the map are converted to XMLNodes also.
|
||||
//
|
||||
// Error will be returned if it is unable to build the map's values into XMLNodes
|
||||
func (b *xmlBuilder) buildMap(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
|
||||
if value.IsNil() { // don't build omitted maps
|
||||
return nil
|
||||
}
|
||||
|
||||
maproot := NewXMLElement(xml.Name{Local: tag.Get("locationName")})
|
||||
current.AddChild(maproot)
|
||||
current = maproot
|
||||
|
||||
kname, vname := "key", "value"
|
||||
if n := tag.Get("locationNameKey"); n != "" {
|
||||
kname = n
|
||||
}
|
||||
if n := tag.Get("locationNameValue"); n != "" {
|
||||
vname = n
|
||||
}
|
||||
|
||||
// sorting is not required for compliance, but it makes testing easier
|
||||
keys := make([]string, value.Len())
|
||||
for i, k := range value.MapKeys() {
|
||||
keys[i] = k.String()
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, k := range keys {
|
||||
v := value.MapIndex(reflect.ValueOf(k))
|
||||
|
||||
mapcur := current
|
||||
if tag.Get("flattened") == "" { // add "entry" tag to non-flat maps
|
||||
child := NewXMLElement(xml.Name{Local: "entry"})
|
||||
mapcur.AddChild(child)
|
||||
mapcur = child
|
||||
}
|
||||
|
||||
kchild := NewXMLElement(xml.Name{Local: kname})
|
||||
kchild.Text = k
|
||||
vchild := NewXMLElement(xml.Name{Local: vname})
|
||||
mapcur.AddChild(kchild)
|
||||
mapcur.AddChild(vchild)
|
||||
|
||||
if err := b.buildValue(v, vchild, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// buildScalar will convert the value into a string and append it as a attribute or child
|
||||
// of the current XMLNode.
|
||||
//
|
||||
// The value will be added as an attribute if tag contains a "xmlAttribute" attribute value.
|
||||
//
|
||||
// Error will be returned if the value type is unsupported.
|
||||
func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
|
||||
var str string
|
||||
switch converted := value.Interface().(type) {
|
||||
case string:
|
||||
str = converted
|
||||
case []byte:
|
||||
if !value.IsNil() {
|
||||
str = base64.StdEncoding.EncodeToString(converted)
|
||||
}
|
||||
case bool:
|
||||
str = strconv.FormatBool(converted)
|
||||
case int64:
|
||||
str = strconv.FormatInt(converted, 10)
|
||||
case int:
|
||||
str = strconv.Itoa(converted)
|
||||
case float64:
|
||||
str = strconv.FormatFloat(converted, 'f', -1, 64)
|
||||
case float32:
|
||||
str = strconv.FormatFloat(float64(converted), 'f', -1, 32)
|
||||
case time.Time:
|
||||
const ISO8601UTC = "2006-01-02T15:04:05Z"
|
||||
str = converted.UTC().Format(ISO8601UTC)
|
||||
default:
|
||||
return fmt.Errorf("unsupported value for param %s: %v (%s)",
|
||||
tag.Get("locationName"), value.Interface(), value.Type().Name())
|
||||
}
|
||||
|
||||
xname := xml.Name{Local: tag.Get("locationName")}
|
||||
if tag.Get("xmlAttribute") != "" { // put into current node's attribute list
|
||||
attr := xml.Attr{Name: xname, Value: str}
|
||||
current.Attr = append(current.Attr, attr)
|
||||
} else { // regular text node
|
||||
current.AddChild(&XMLNode{Name: xname, Text: str})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
266
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/xml/xmlutil/unmarshal.go
generated
vendored
Normal file
266
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/xml/xmlutil/unmarshal.go
generated
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
package xmlutil
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// UnmarshalXML deserializes an xml.Decoder into the container v. V
|
||||
// needs to match the shape of the XML expected to be decoded.
|
||||
// If the shape doesn't match unmarshaling will fail.
|
||||
func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error {
|
||||
n, _ := XMLToStruct(d, nil)
|
||||
if n.Children != nil {
|
||||
for _, root := range n.Children {
|
||||
for _, c := range root {
|
||||
if wrappedChild, ok := c.Children[wrapper]; ok {
|
||||
c = wrappedChild[0] // pull out wrapped element
|
||||
}
|
||||
|
||||
err := parse(reflect.ValueOf(v), c, "")
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// parse deserializes any value from the XMLNode. The type tag is used to infer the type, or reflect
|
||||
// will be used to determine the type from r.
|
||||
func parse(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
||||
rtype := r.Type()
|
||||
if rtype.Kind() == reflect.Ptr {
|
||||
rtype = rtype.Elem() // check kind of actual element type
|
||||
}
|
||||
|
||||
t := tag.Get("type")
|
||||
if t == "" {
|
||||
switch rtype.Kind() {
|
||||
case reflect.Struct:
|
||||
t = "structure"
|
||||
case reflect.Slice:
|
||||
t = "list"
|
||||
case reflect.Map:
|
||||
t = "map"
|
||||
}
|
||||
}
|
||||
|
||||
switch t {
|
||||
case "structure":
|
||||
if field, ok := rtype.FieldByName("SDKShapeTraits"); ok {
|
||||
tag = field.Tag
|
||||
}
|
||||
return parseStruct(r, node, tag)
|
||||
case "list":
|
||||
return parseList(r, node, tag)
|
||||
case "map":
|
||||
return parseMap(r, node, tag)
|
||||
default:
|
||||
return parseScalar(r, node, tag)
|
||||
}
|
||||
}
|
||||
|
||||
// parseStruct deserializes a structure and its fields from an XMLNode. Any nested
|
||||
// types in the structure will also be deserialized.
|
||||
func parseStruct(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
||||
t := r.Type()
|
||||
if r.Kind() == reflect.Ptr {
|
||||
if r.IsNil() { // create the structure if it's nil
|
||||
s := reflect.New(r.Type().Elem())
|
||||
r.Set(s)
|
||||
r = s
|
||||
}
|
||||
|
||||
r = r.Elem()
|
||||
t = t.Elem()
|
||||
}
|
||||
|
||||
// unwrap any payloads
|
||||
if payload := tag.Get("payload"); payload != "" {
|
||||
field, _ := t.FieldByName(payload)
|
||||
return parseStruct(r.FieldByName(payload), node, field.Tag)
|
||||
}
|
||||
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
if c := field.Name[0:1]; strings.ToLower(c) == c {
|
||||
continue // ignore unexported fields
|
||||
}
|
||||
|
||||
// figure out what this field is called
|
||||
name := field.Name
|
||||
if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" {
|
||||
name = field.Tag.Get("locationNameList")
|
||||
} else if locName := field.Tag.Get("locationName"); locName != "" {
|
||||
name = locName
|
||||
}
|
||||
|
||||
// try to find the field by name in elements
|
||||
elems := node.Children[name]
|
||||
|
||||
if elems == nil { // try to find the field in attributes
|
||||
for _, a := range node.Attr {
|
||||
if name == a.Name.Local {
|
||||
// turn this into a text node for de-serializing
|
||||
elems = []*XMLNode{{Text: a.Value}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
member := r.FieldByName(field.Name)
|
||||
for _, elem := range elems {
|
||||
err := parse(member, elem, field.Tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseList deserializes a list of values from an XML node. Each list entry
|
||||
// will also be deserialized.
|
||||
func parseList(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
||||
t := r.Type()
|
||||
|
||||
if tag.Get("flattened") == "" { // look at all item entries
|
||||
mname := "member"
|
||||
if name := tag.Get("locationNameList"); name != "" {
|
||||
mname = name
|
||||
}
|
||||
|
||||
if Children, ok := node.Children[mname]; ok {
|
||||
if r.IsNil() {
|
||||
r.Set(reflect.MakeSlice(t, len(Children), len(Children)))
|
||||
}
|
||||
|
||||
for i, c := range Children {
|
||||
err := parse(r.Index(i), c, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // flattened list means this is a single element
|
||||
if r.IsNil() {
|
||||
r.Set(reflect.MakeSlice(t, 0, 0))
|
||||
}
|
||||
|
||||
childR := reflect.Zero(t.Elem())
|
||||
r.Set(reflect.Append(r, childR))
|
||||
err := parse(r.Index(r.Len()-1), node, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseMap deserializes a map from an XMLNode. The direct children of the XMLNode
|
||||
// will also be deserialized as map entries.
|
||||
func parseMap(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
||||
if r.IsNil() {
|
||||
r.Set(reflect.MakeMap(r.Type()))
|
||||
}
|
||||
|
||||
if tag.Get("flattened") == "" { // look at all child entries
|
||||
for _, entry := range node.Children["entry"] {
|
||||
parseMapEntry(r, entry, tag)
|
||||
}
|
||||
} else { // this element is itself an entry
|
||||
parseMapEntry(r, node, tag)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseMapEntry deserializes a map entry from a XML node.
|
||||
func parseMapEntry(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
||||
kname, vname := "key", "value"
|
||||
if n := tag.Get("locationNameKey"); n != "" {
|
||||
kname = n
|
||||
}
|
||||
if n := tag.Get("locationNameValue"); n != "" {
|
||||
vname = n
|
||||
}
|
||||
|
||||
keys, ok := node.Children[kname]
|
||||
values := node.Children[vname]
|
||||
if ok {
|
||||
for i, key := range keys {
|
||||
keyR := reflect.ValueOf(key.Text)
|
||||
value := values[i]
|
||||
valueR := reflect.New(r.Type().Elem()).Elem()
|
||||
|
||||
parse(valueR, value, "")
|
||||
r.SetMapIndex(keyR, valueR)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseScaller deserializes an XMLNode value into a concrete type based on the
|
||||
// interface type of r.
|
||||
//
|
||||
// Error is returned if the deserialization fails due to invalid type conversion,
|
||||
// or unsupported interface type.
|
||||
func parseScalar(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
||||
switch r.Interface().(type) {
|
||||
case *string:
|
||||
r.Set(reflect.ValueOf(&node.Text))
|
||||
return nil
|
||||
case string:
|
||||
r.Set(reflect.ValueOf(node.Text))
|
||||
return nil
|
||||
case []byte:
|
||||
b, err := base64.StdEncoding.DecodeString(node.Text)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.Set(reflect.ValueOf(b))
|
||||
case *bool:
|
||||
v, err := strconv.ParseBool(node.Text)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.Set(reflect.ValueOf(&v))
|
||||
case *int64:
|
||||
v, err := strconv.ParseInt(node.Text, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.Set(reflect.ValueOf(&v))
|
||||
case *float64:
|
||||
v, err := strconv.ParseFloat(node.Text, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.Set(reflect.ValueOf(&v))
|
||||
case *time.Time:
|
||||
const ISO8601UTC = "2006-01-02T15:04:05Z"
|
||||
t, err := time.Parse(ISO8601UTC, node.Text)
|
||||
if err != nil {
|
||||
t, err = time.Parse("2006-01-02T15:04:05-07:00", node.Text)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
r.Set(reflect.ValueOf(&t))
|
||||
default:
|
||||
return fmt.Errorf("unsupported value: %v (%s)", r.Interface(), r.Type())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
105
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/xml/xmlutil/xml_to_struct.go
generated
vendored
Normal file
105
vendor/github.com/ks3sdklib/aws-sdk-go/internal/protocol/xml/xmlutil/xml_to_struct.go
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
package xmlutil
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"io"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// A XMLNode contains the values to be encoded or decoded.
|
||||
type XMLNode struct {
|
||||
Name xml.Name `json:",omitempty"`
|
||||
Children map[string][]*XMLNode `json:",omitempty"`
|
||||
Text string `json:",omitempty"`
|
||||
Attr []xml.Attr `json:",omitempty"`
|
||||
}
|
||||
|
||||
// NewXMLElement returns a pointer to a new XMLNode initialized to default values.
|
||||
func NewXMLElement(name xml.Name) *XMLNode {
|
||||
return &XMLNode{
|
||||
Name: name,
|
||||
Children: map[string][]*XMLNode{},
|
||||
Attr: []xml.Attr{},
|
||||
}
|
||||
}
|
||||
|
||||
// AddChild adds child to the XMLNode.
|
||||
func (n *XMLNode) AddChild(child *XMLNode) {
|
||||
if _, ok := n.Children[child.Name.Local]; !ok {
|
||||
n.Children[child.Name.Local] = []*XMLNode{}
|
||||
}
|
||||
n.Children[child.Name.Local] = append(n.Children[child.Name.Local], child)
|
||||
}
|
||||
|
||||
// XMLToStruct converts a xml.Decoder stream to XMLNode with nested values.
|
||||
func XMLToStruct(d *xml.Decoder, s *xml.StartElement) (*XMLNode, error) {
|
||||
out := &XMLNode{}
|
||||
for {
|
||||
tok, err := d.Token()
|
||||
if tok == nil || err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
|
||||
switch typed := tok.(type) {
|
||||
case xml.CharData:
|
||||
out.Text = string(typed.Copy())
|
||||
case xml.StartElement:
|
||||
el := typed.Copy()
|
||||
out.Attr = el.Attr
|
||||
if out.Children == nil {
|
||||
out.Children = map[string][]*XMLNode{}
|
||||
}
|
||||
|
||||
name := typed.Name.Local
|
||||
slice := out.Children[name]
|
||||
if slice == nil {
|
||||
slice = []*XMLNode{}
|
||||
}
|
||||
node, e := XMLToStruct(d, &el)
|
||||
if e != nil {
|
||||
return out, e
|
||||
}
|
||||
node.Name = typed.Name
|
||||
slice = append(slice, node)
|
||||
out.Children[name] = slice
|
||||
case xml.EndElement:
|
||||
if s != nil && s.Name.Local == typed.Name.Local { // matching end token
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// StructToXML writes an XMLNode to a xml.Encoder as tokens.
|
||||
func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error {
|
||||
e.EncodeToken(xml.StartElement{Name: node.Name, Attr: node.Attr})
|
||||
|
||||
if node.Text != "" {
|
||||
e.EncodeToken(xml.CharData(node.Text))
|
||||
} else if sorted {
|
||||
sortedNames := []string{}
|
||||
for k := range node.Children {
|
||||
sortedNames = append(sortedNames, k)
|
||||
}
|
||||
sort.Strings(sortedNames)
|
||||
|
||||
for _, k := range sortedNames {
|
||||
for _, v := range node.Children[k] {
|
||||
StructToXML(e, v, sorted)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, c := range node.Children {
|
||||
for _, v := range c {
|
||||
StructToXML(e, v, sorted)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.EncodeToken(xml.EndElement{Name: node.Name})
|
||||
return e.Flush()
|
||||
}
|
||||
77
vendor/github.com/ks3sdklib/aws-sdk-go/internal/signer/open_api/open_api.go
generated
vendored
Normal file
77
vendor/github.com/ks3sdklib/aws-sdk-go/internal/signer/open_api/open_api.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
package open_api
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/credentials"
|
||||
"net/url"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Sign(req *aws.Request) {
|
||||
if req.Config.Credentials == credentials.AnonymousCredentials {
|
||||
return
|
||||
}
|
||||
|
||||
CredValues, err := req.Config.Credentials.Get()
|
||||
if err != nil {
|
||||
req.Error = err
|
||||
return
|
||||
}
|
||||
|
||||
params := map[string]string{
|
||||
//固定参数
|
||||
"Accesskey": CredValues.AccessKeyID,
|
||||
"Service": "ks3bill",
|
||||
"Version": "v1",
|
||||
"Timestamp": time.Now().UTC().Format("2006-01-02T15:04:05Z"),
|
||||
"SignatureVersion": "1.0",
|
||||
"SignatureMethod": "HMAC-SHA256",
|
||||
}
|
||||
|
||||
query := req.HTTPRequest.URL.Query()
|
||||
for k, v := range params {
|
||||
query.Set(k, v)
|
||||
}
|
||||
|
||||
queryString := getCanonicalizedQueryString(query)
|
||||
cfg := req.Config
|
||||
cfg.LogDebug("%s", "---[ QUERY STRING ]--------------------------------")
|
||||
cfg.LogDebug("%s", queryString)
|
||||
cfg.LogDebug("-----------------------------------------------------")
|
||||
|
||||
signature := getSignature(queryString, CredValues.SecretAccessKey)
|
||||
query.Set("Signature", signature)
|
||||
req.HTTPRequest.URL.RawQuery = query.Encode()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// getCanonicalizedQueryString 构建规范化查询字符串
|
||||
func getCanonicalizedQueryString(params url.Values) string {
|
||||
//对参数键进行排序
|
||||
keys := make([]string, 0, len(params))
|
||||
for k := range params {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
//构建待签名字符串
|
||||
var strEncode string
|
||||
for _, k := range keys {
|
||||
strEncode += url.QueryEscape(k) + "=" + url.QueryEscape(params.Get(k)) + "&"
|
||||
}
|
||||
strEncode = strEncode[:len(strEncode)-1]
|
||||
return strEncode
|
||||
}
|
||||
|
||||
// getSignature 简易签名函数,使用HMAC-SHA256算法
|
||||
func getSignature(queryString, secretKey string) string {
|
||||
//生成HMAC-SHA256签名
|
||||
h := hmac.New(sha256.New, []byte(secretKey))
|
||||
h.Write([]byte(queryString))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
371
vendor/github.com/ks3sdklib/aws-sdk-go/internal/signer/v2/v2.go
generated
vendored
Normal file
371
vendor/github.com/ks3sdklib/aws-sdk-go/internal/signer/v2/v2.go
generated
vendored
Normal file
@@ -0,0 +1,371 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/awsutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/credentials"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/rest"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
const (
|
||||
authHeaderPrefix = "AWS"
|
||||
timeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
|
||||
)
|
||||
|
||||
var signQuerys = map[string]bool{
|
||||
"acl": true,
|
||||
"lifecycle": true,
|
||||
"location": true,
|
||||
"logging": true,
|
||||
"notification": true,
|
||||
"policy": true,
|
||||
"requestPayment": true,
|
||||
"torrent": true,
|
||||
"uploadId": true,
|
||||
"uploads": true,
|
||||
"versionId": true,
|
||||
"versioning": true,
|
||||
"versions": true,
|
||||
"website": true,
|
||||
"delete": true,
|
||||
"thumbnail": true,
|
||||
"cors": true,
|
||||
"pfop": true,
|
||||
"querypfop": true,
|
||||
"partNumber": true,
|
||||
"response-content-type": true,
|
||||
"response-content-language": true,
|
||||
"response-expires": true,
|
||||
"response-cache-control": true,
|
||||
"response-content-disposition": true,
|
||||
"response-content-encoding": true,
|
||||
"tagging": true,
|
||||
"fetch": true,
|
||||
"copy": true,
|
||||
"mirror": true,
|
||||
"restore": true,
|
||||
"append": true,
|
||||
"position": true,
|
||||
"decompresspolicy": true,
|
||||
"retention": true,
|
||||
"crr": true,
|
||||
"inventory": true,
|
||||
"recycle": true,
|
||||
"recover": true,
|
||||
"clear": true,
|
||||
"id": true,
|
||||
"continuation-token": true,
|
||||
"dataRedundancySwitch": true,
|
||||
"bucketqos": true,
|
||||
"requesterqos": true,
|
||||
"encryption": true,
|
||||
"accessmonitor": true,
|
||||
"transferAcceleration": true,
|
||||
"VpcAccessBlock": true,
|
||||
}
|
||||
|
||||
type signer struct {
|
||||
Service *aws.Service
|
||||
Request *http.Request
|
||||
Time time.Time
|
||||
ExpireTime int64
|
||||
ServiceName string
|
||||
Region string
|
||||
CredValues credentials.Value
|
||||
Credentials *credentials.Credentials
|
||||
Query url.Values
|
||||
Body io.ReadSeeker
|
||||
Debug uint
|
||||
Logger io.Writer
|
||||
|
||||
isPresign bool
|
||||
formattedTime string
|
||||
|
||||
canonicalHeaders string
|
||||
canonicalResource string
|
||||
stringToSign string
|
||||
signature string
|
||||
authorization string
|
||||
awsRequest *aws.Request
|
||||
}
|
||||
|
||||
func Sign(req *aws.Request) {
|
||||
if req.Service.Config.Credentials == credentials.AnonymousCredentials {
|
||||
return
|
||||
}
|
||||
|
||||
region := req.Service.SigningRegion
|
||||
if region == "" {
|
||||
region = req.Service.Config.Region
|
||||
}
|
||||
|
||||
name := req.Service.SigningName
|
||||
if name == "" {
|
||||
name = req.Service.ServiceName
|
||||
}
|
||||
|
||||
s := signer{
|
||||
Service: req.Service,
|
||||
Request: req.HTTPRequest,
|
||||
Time: req.Time,
|
||||
ExpireTime: req.ExpireTime,
|
||||
Query: req.HTTPRequest.URL.Query(),
|
||||
Body: req.Body,
|
||||
ServiceName: name,
|
||||
Region: region,
|
||||
Credentials: req.Service.Config.Credentials,
|
||||
Debug: req.Service.Config.LogLevel,
|
||||
Logger: req.Service.Config.Logger,
|
||||
awsRequest: req,
|
||||
}
|
||||
|
||||
req.Error = s.sign()
|
||||
}
|
||||
|
||||
func (v2 *signer) sign() error {
|
||||
if v2.ExpireTime != 0 {
|
||||
v2.isPresign = true
|
||||
}
|
||||
|
||||
if v2.isRequestSigned() {
|
||||
if !v2.Credentials.IsExpired() {
|
||||
// If the request is already signed, and the credentials have not
|
||||
// expired yet ignore the signing request.
|
||||
return nil
|
||||
}
|
||||
|
||||
// The credentials have expired for this request. The current signing
|
||||
// is invalid, and needs to be request because the request will fail.
|
||||
if v2.isPresign {
|
||||
v2.removePresign()
|
||||
// Update the request's query string to ensure the values stays in
|
||||
// sync in the case retrieving the new credentials fails.
|
||||
v2.Request.URL.RawQuery = v2.Query.Encode()
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
v2.CredValues, err = v2.Credentials.Get()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v2.build()
|
||||
|
||||
v2.logSigningInfo()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v2 *signer) logSigningInfo() {
|
||||
cfg := v2.Service.Config
|
||||
cfg.LogDebug("%s", "---[ STRING TO SIGN ]--------------------------------")
|
||||
cfg.LogDebug("%s", v2.stringToSign)
|
||||
if v2.isPresign {
|
||||
cfg.LogDebug("---[ SIGNED URL ]--------------------------------")
|
||||
cfg.LogDebug("%s", v2.Request.URL)
|
||||
}
|
||||
cfg.LogDebug("-----------------------------------------------------")
|
||||
}
|
||||
|
||||
func (v2 *signer) build() {
|
||||
v2.buildTime() // no depends
|
||||
v2.buildCanonicalHeaders() // depends on cred string
|
||||
v2.buildCanonicalResource() // depends on canon headers / signed headers
|
||||
v2.buildStringToSign() // depends on canon string
|
||||
v2.buildSignature() // depends on string to sign
|
||||
|
||||
if v2.isPresign {
|
||||
var querys url.Values
|
||||
querys = make(map[string][]string)
|
||||
querys.Add("Signature", v2.signature)
|
||||
querys.Add("AWSAccessKeyId", v2.CredValues.AccessKeyID)
|
||||
v2.Request.URL.RawQuery += "&" + querys.Encode()
|
||||
} else {
|
||||
v2.Request.Header.Set("Authorization", "AWS "+v2.CredValues.AccessKeyID+":"+v2.signature)
|
||||
}
|
||||
}
|
||||
|
||||
func (v2 *signer) buildTime() {
|
||||
v2.formattedTime = v2.Time.UTC().Format(timeFormat)
|
||||
|
||||
if v2.isPresign {
|
||||
duration := int64(v2.ExpireTime)
|
||||
v2.Query.Set("Expires", strconv.FormatInt(duration, 10))
|
||||
} else {
|
||||
v2.Request.Header.Set("Date", v2.formattedTime)
|
||||
}
|
||||
}
|
||||
|
||||
func (v2 *signer) buildCanonicalHeaders() {
|
||||
var headers []string
|
||||
for k, v := range v2.Request.Header {
|
||||
if strings.HasPrefix(k, "X-Amz-") {
|
||||
key := strings.ToLower(http.CanonicalHeaderKey(k))
|
||||
v2.Request.Header[key] = v
|
||||
v2.Request.Header.Del(http.CanonicalHeaderKey(k))
|
||||
headers = append(headers, key)
|
||||
}
|
||||
}
|
||||
sort.Strings(headers)
|
||||
|
||||
headerValues := make([]string, len(headers))
|
||||
for i, k := range headers {
|
||||
key := strings.ToLower(http.CanonicalHeaderKey(k))
|
||||
headerValues[i] = key + ":" + strings.Join(v2.Request.Header[key], ",")
|
||||
}
|
||||
|
||||
v2.canonicalHeaders = strings.Join(headerValues, "\n")
|
||||
}
|
||||
|
||||
func (v2 *signer) buildCanonicalResource() {
|
||||
endpoint := v2.Service.Endpoint
|
||||
|
||||
v2.Request.URL.RawQuery = strings.Replace(v2.Query.Encode(), "+", "%20", -1)
|
||||
url := v2.Request.URL.String()
|
||||
//在aws.service.go,buildEndpoint会把sheme也加上
|
||||
pathStyle := strings.HasPrefix(url, endpoint)
|
||||
uri := v2.Request.URL.Opaque
|
||||
bucketInHost := ""
|
||||
if !pathStyle {
|
||||
if strings.HasPrefix(url, "http://") {
|
||||
url = url[7:]
|
||||
endpoint = endpoint[7:]
|
||||
} else if strings.HasPrefix(url, "https://") {
|
||||
url = url[8:]
|
||||
endpoint = endpoint[8:]
|
||||
}
|
||||
bucketInHost = url[0 : strings.Index(url, endpoint)-1]
|
||||
}
|
||||
if uri != "" {
|
||||
uris := strings.Split(uri, "/")[3:]
|
||||
append := false
|
||||
if len(uris) == 1 && uris[0] != "" && bucketInHost == "" {
|
||||
//只有bucket
|
||||
append = true
|
||||
} else if len(uris) == 0 && bucketInHost != "" {
|
||||
append = true
|
||||
}
|
||||
uri = "/" + strings.Join(strings.Split(uri, "/")[3:], "/")
|
||||
if bucketInHost != "" {
|
||||
uri = "/" + bucketInHost + uri
|
||||
}
|
||||
if v2.awsRequest.Config.DomainMode {
|
||||
b := awsutil.ValuesAtPath(v2.awsRequest.Params, "Bucket")
|
||||
bucket := b[0].(string)
|
||||
uri = "/" + bucket + uri
|
||||
append = false
|
||||
}
|
||||
if append {
|
||||
uri += "/"
|
||||
}
|
||||
} else {
|
||||
uri = v2.Request.URL.Path
|
||||
}
|
||||
if uri == "" {
|
||||
uri = "/"
|
||||
}
|
||||
|
||||
if v2.ServiceName != "s3" {
|
||||
uri = rest.EscapePath(uri, false)
|
||||
}
|
||||
|
||||
var querys []string
|
||||
for k := range v2.Query {
|
||||
if _, ok := signQuerys[k]; ok {
|
||||
querys = append(querys, k)
|
||||
}
|
||||
}
|
||||
sort.Strings(querys)
|
||||
|
||||
queryValues := make([]string, len(querys))
|
||||
for i, k := range querys {
|
||||
v := v2.Query[k]
|
||||
vString := strings.Join(v, ",")
|
||||
if vString != "" {
|
||||
queryValues[i] = k + "=" + vString
|
||||
} else {
|
||||
queryValues[i] = k
|
||||
}
|
||||
}
|
||||
queryString := strings.Join(queryValues, "&")
|
||||
if queryString == "" {
|
||||
v2.canonicalResource = uri
|
||||
} else {
|
||||
v2.canonicalResource = uri + "?" + queryString
|
||||
}
|
||||
}
|
||||
|
||||
func (v2 *signer) buildStringToSign() {
|
||||
md5list := v2.Request.Header["Content-Md5"]
|
||||
md5 := ""
|
||||
if len(md5list) > 0 {
|
||||
md5 = v2.Request.Header["Content-Md5"][0]
|
||||
}
|
||||
|
||||
typelist := v2.Request.Header["Content-Type"]
|
||||
contenttype := ""
|
||||
if len(typelist) > 0 {
|
||||
contenttype = v2.Request.Header["Content-Type"][0]
|
||||
}
|
||||
signItems := []string{v2.Request.Method, md5, contenttype}
|
||||
if v2.isPresign {
|
||||
signItems = append(signItems, v2.Query["Expires"][0])
|
||||
} else {
|
||||
signItems = append(signItems, v2.formattedTime)
|
||||
}
|
||||
if v2.canonicalHeaders != "" {
|
||||
signItems = append(signItems, v2.canonicalHeaders)
|
||||
}
|
||||
signItems = append(signItems, v2.canonicalResource)
|
||||
|
||||
v2.stringToSign = strings.Join(signItems, "\n")
|
||||
|
||||
}
|
||||
|
||||
func (v2 *signer) buildSignature() {
|
||||
secret := v2.CredValues.SecretAccessKey
|
||||
signature := string(base64Encode(makeHmac([]byte(secret), []byte(v2.stringToSign))))
|
||||
v2.signature = signature
|
||||
}
|
||||
|
||||
// isRequestSigned returns if the request is currently signed or presigned
|
||||
func (v2 *signer) isRequestSigned() bool {
|
||||
if v2.isPresign && v2.Query.Get("Signature") != "" {
|
||||
return true
|
||||
}
|
||||
if v2.Request.Header.Get("Authorization") != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// unsign removes signing flags for both signed and presigned requests.
|
||||
func (v2 *signer) removePresign() {
|
||||
v2.Query.Del("AWSAccessKeyId")
|
||||
v2.Query.Del("Signature")
|
||||
v2.Query.Del("Expires")
|
||||
|
||||
}
|
||||
|
||||
func makeHmac(key []byte, data []byte) []byte {
|
||||
hash := hmac.New(sha1.New, key)
|
||||
hash.Write(data)
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
func base64Encode(src []byte) []byte {
|
||||
return []byte(base64.StdEncoding.EncodeToString(src))
|
||||
}
|
||||
369
vendor/github.com/ks3sdklib/aws-sdk-go/internal/signer/v4/v4.go
generated
vendored
Normal file
369
vendor/github.com/ks3sdklib/aws-sdk-go/internal/signer/v4/v4.go
generated
vendored
Normal file
@@ -0,0 +1,369 @@
|
||||
// Package v4 implements signing for AWS V4 signer
|
||||
package v4
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/credentials"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/rest"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
const (
|
||||
authHeaderPrefix = "AWS4-HMAC-SHA256"
|
||||
timeFormat = "20060102T150405Z"
|
||||
shortTimeFormat = "20060102"
|
||||
)
|
||||
|
||||
var ignoredHeaders = map[string]bool{
|
||||
"Authorization": true,
|
||||
"Content-Type": true,
|
||||
"Content-Length": true,
|
||||
"User-Agent": true,
|
||||
}
|
||||
|
||||
type signer struct {
|
||||
Service *aws.Service
|
||||
Request *http.Request
|
||||
Time time.Time
|
||||
ExpireTime int64
|
||||
ServiceName string
|
||||
Region string
|
||||
CredValues credentials.Value
|
||||
Credentials *credentials.Credentials
|
||||
Query url.Values
|
||||
Body io.ReadSeeker
|
||||
Debug uint
|
||||
Logger io.Writer
|
||||
|
||||
isPresign bool
|
||||
isSignBody bool
|
||||
formattedTime string
|
||||
formattedShortTime string
|
||||
|
||||
signedHeaders string
|
||||
canonicalHeaders string
|
||||
canonicalString string
|
||||
credentialString string
|
||||
stringToSign string
|
||||
signature string
|
||||
authorization string
|
||||
}
|
||||
|
||||
// Sign requests with signature version 4.
|
||||
//
|
||||
// Will sign the requests with the service config's Credentials object
|
||||
// Signing is skipped if the credentials is the credentials.AnonymousCredentials
|
||||
// object.
|
||||
func Sign(req *aws.Request) {
|
||||
// If the request does not need to be signed ignore the signing of the
|
||||
// request if the AnonymousCredentials object is used.
|
||||
if req.Service.Config.Credentials == credentials.AnonymousCredentials {
|
||||
return
|
||||
}
|
||||
|
||||
region := req.Service.SigningRegion
|
||||
if region == "" {
|
||||
region = req.Service.Config.Region
|
||||
}
|
||||
|
||||
name := req.Service.SigningName
|
||||
if name == "" {
|
||||
name = req.Service.ServiceName
|
||||
}
|
||||
|
||||
s := signer{
|
||||
Service: req.Service,
|
||||
Request: req.HTTPRequest,
|
||||
Time: req.Time,
|
||||
ExpireTime: req.ExpireTime,
|
||||
Query: req.HTTPRequest.URL.Query(),
|
||||
Body: req.Body,
|
||||
ServiceName: name,
|
||||
Region: region,
|
||||
Credentials: req.Service.Config.Credentials,
|
||||
Debug: req.Service.Config.LogLevel,
|
||||
Logger: req.Service.Config.Logger,
|
||||
}
|
||||
if req.Service.Config.SignerVersion == "V4_UNSIGNED_PAYLOAD_SIGNER" {
|
||||
s.isSignBody = false
|
||||
} else {
|
||||
s.isSignBody = true
|
||||
}
|
||||
req.Error = s.sign()
|
||||
}
|
||||
|
||||
func (v4 *signer) sign() error {
|
||||
if v4.ExpireTime != 0 {
|
||||
v4.isPresign = true
|
||||
}
|
||||
|
||||
if v4.isRequestSigned() {
|
||||
if !v4.Credentials.IsExpired() {
|
||||
// If the request is already signed, and the credentials have not
|
||||
// expired yet ignore the signing request.
|
||||
return nil
|
||||
}
|
||||
|
||||
// The credentials have expired for this request. The current signing
|
||||
// is invalid, and needs to be request because the request will fail.
|
||||
if v4.isPresign {
|
||||
v4.removePresign()
|
||||
// Update the request's query string to ensure the values stays in
|
||||
// sync in the case retrieving the new credentials fails.
|
||||
v4.Request.URL.RawQuery = v4.Query.Encode()
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
v4.CredValues, err = v4.Credentials.Get()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if v4.isPresign {
|
||||
v4.Query.Set("X-Amz-Algorithm", authHeaderPrefix)
|
||||
if v4.CredValues.SessionToken != "" {
|
||||
v4.Query.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
|
||||
} else {
|
||||
v4.Query.Del("X-Amz-Security-Token")
|
||||
}
|
||||
} else if v4.CredValues.SessionToken != "" {
|
||||
v4.Request.Header.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
|
||||
}
|
||||
|
||||
v4.build()
|
||||
|
||||
v4.logSigningInfo()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v4 *signer) logSigningInfo() {
|
||||
cfg := v4.Service.Config
|
||||
cfg.LogDebug("%s", "---[ CANONICAL STRING ]-----------------------------")
|
||||
cfg.LogDebug("%s", v4.canonicalString)
|
||||
cfg.LogDebug("%s", "---[ STRING TO SIGN ]--------------------------------")
|
||||
cfg.LogDebug("%s", v4.stringToSign)
|
||||
if v4.isPresign {
|
||||
cfg.LogDebug("---[ SIGNED URL ]--------------------------------")
|
||||
cfg.LogDebug("%s", v4.Request.URL)
|
||||
}
|
||||
cfg.LogDebug("-----------------------------------------------------")
|
||||
}
|
||||
|
||||
func (v4 *signer) build() {
|
||||
v4.buildTime() // no depends
|
||||
v4.buildCredentialString() // no depends
|
||||
if v4.isPresign {
|
||||
v4.buildQuery() // no depends
|
||||
}
|
||||
v4.buildCanonicalHeaders() // depends on cred string
|
||||
v4.buildCanonicalString() // depends on canon headers / signed headers
|
||||
v4.buildStringToSign() // depends on canon string
|
||||
v4.buildSignature() // depends on string to sign
|
||||
|
||||
if v4.isPresign {
|
||||
v4.Request.URL.RawQuery += "&X-Amz-Signature=" + v4.signature
|
||||
} else {
|
||||
parts := []string{
|
||||
authHeaderPrefix + " Credential=" + v4.CredValues.AccessKeyID + "/" + v4.credentialString,
|
||||
"SignedHeaders=" + v4.signedHeaders,
|
||||
"Signature=" + v4.signature,
|
||||
}
|
||||
v4.Request.Header.Set("Authorization", strings.Join(parts, ", "))
|
||||
}
|
||||
}
|
||||
|
||||
func (v4 *signer) buildTime() {
|
||||
v4.formattedTime = v4.Time.UTC().Format(timeFormat)
|
||||
v4.formattedShortTime = v4.Time.UTC().Format(shortTimeFormat)
|
||||
|
||||
if v4.isPresign {
|
||||
duration := int64(v4.ExpireTime)
|
||||
v4.Query.Set("X-Amz-Date", v4.formattedTime)
|
||||
v4.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10))
|
||||
} else {
|
||||
v4.Request.Header.Set("X-Amz-Date", v4.formattedTime)
|
||||
}
|
||||
}
|
||||
|
||||
func (v4 *signer) buildCredentialString() {
|
||||
v4.credentialString = strings.Join([]string{
|
||||
v4.formattedShortTime,
|
||||
v4.Region,
|
||||
v4.ServiceName,
|
||||
"aws4_request",
|
||||
}, "/")
|
||||
|
||||
if v4.isPresign {
|
||||
v4.Query.Set("X-Amz-Credential", v4.CredValues.AccessKeyID+"/"+v4.credentialString)
|
||||
}
|
||||
}
|
||||
|
||||
func (v4 *signer) buildQuery() {
|
||||
for k, h := range v4.Request.Header {
|
||||
if strings.HasPrefix(http.CanonicalHeaderKey(k), "X-Amz-") {
|
||||
continue // never hoist x-amz-* headers, they must be signed
|
||||
}
|
||||
if _, ok := ignoredHeaders[http.CanonicalHeaderKey(k)]; ok {
|
||||
continue // never hoist ignored headers
|
||||
}
|
||||
|
||||
v4.Request.Header.Del(k)
|
||||
v4.Query.Del(k)
|
||||
for _, v := range h {
|
||||
v4.Query.Add(k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (v4 *signer) buildCanonicalHeaders() {
|
||||
var headers []string
|
||||
headers = append(headers, "host")
|
||||
for k := range v4.Request.Header {
|
||||
if _, ok := ignoredHeaders[http.CanonicalHeaderKey(k)]; ok {
|
||||
continue // ignored header
|
||||
}
|
||||
headers = append(headers, strings.ToLower(k))
|
||||
}
|
||||
sort.Strings(headers)
|
||||
|
||||
v4.signedHeaders = strings.Join(headers, ";")
|
||||
|
||||
if v4.isPresign {
|
||||
v4.Query.Set("X-Amz-SignedHeaders", v4.signedHeaders)
|
||||
}
|
||||
|
||||
headerValues := make([]string, len(headers))
|
||||
for i, k := range headers {
|
||||
if k == "host" {
|
||||
headerValues[i] = "host:" + v4.Request.URL.Host
|
||||
} else {
|
||||
headerValues[i] = k + ":" +
|
||||
strings.Join(v4.Request.Header[http.CanonicalHeaderKey(k)], ",")
|
||||
}
|
||||
}
|
||||
|
||||
v4.canonicalHeaders = strings.Join(headerValues, "\n")
|
||||
}
|
||||
|
||||
func (v4 *signer) buildCanonicalString() {
|
||||
v4.Request.URL.RawQuery = strings.Replace(v4.Query.Encode(), "+", "%20", -1)
|
||||
uri := strings.Replace(v4.Request.URL.Opaque, "%2F", "/", -1)
|
||||
if uri != "" {
|
||||
uri = "/" + strings.Join(strings.Split(uri, "/")[3:], "/")
|
||||
} else {
|
||||
uri = v4.Request.URL.Path
|
||||
}
|
||||
if uri == "" {
|
||||
uri = "/"
|
||||
}
|
||||
|
||||
if v4.ServiceName != "s3" {
|
||||
uri = rest.EscapePath(uri, false)
|
||||
}
|
||||
|
||||
v4.canonicalString = strings.Join([]string{
|
||||
v4.Request.Method,
|
||||
uri,
|
||||
v4.Request.URL.RawQuery,
|
||||
v4.canonicalHeaders + "\n",
|
||||
v4.signedHeaders,
|
||||
v4.bodyDigest(),
|
||||
}, "\n")
|
||||
}
|
||||
|
||||
func (v4 *signer) buildStringToSign() {
|
||||
v4.stringToSign = strings.Join([]string{
|
||||
authHeaderPrefix,
|
||||
v4.formattedTime,
|
||||
v4.credentialString,
|
||||
hex.EncodeToString(makeSha256([]byte(v4.canonicalString))),
|
||||
}, "\n")
|
||||
}
|
||||
|
||||
func (v4 *signer) buildSignature() {
|
||||
secret := v4.CredValues.SecretAccessKey
|
||||
date := makeHmac([]byte("AWS4"+secret), []byte(v4.formattedShortTime))
|
||||
region := makeHmac(date, []byte(v4.Region))
|
||||
service := makeHmac(region, []byte(v4.ServiceName))
|
||||
credentials := makeHmac(service, []byte("aws4_request"))
|
||||
signature := makeHmac(credentials, []byte(v4.stringToSign))
|
||||
v4.signature = hex.EncodeToString(signature)
|
||||
}
|
||||
|
||||
func (v4 *signer) bodyDigest() string {
|
||||
hash := v4.Request.Header.Get("X-Amz-Content-Sha256")
|
||||
if hash == "" {
|
||||
if v4.isPresign && v4.ServiceName == "s3" {
|
||||
hash = "UNSIGNED-PAYLOAD"
|
||||
} else {
|
||||
if v4.isSignBody {
|
||||
if v4.Body == nil {
|
||||
hash = hex.EncodeToString(makeSha256([]byte{}))
|
||||
} else {
|
||||
hash = hex.EncodeToString(makeSha256Reader(v4.Body))
|
||||
}
|
||||
} else {
|
||||
hash = "UNSIGNED-PAYLOAD"
|
||||
}
|
||||
}
|
||||
v4.Request.Header.Add("X-Amz-Content-Sha256", hash)
|
||||
}
|
||||
return hash
|
||||
}
|
||||
|
||||
// isRequestSigned returns if the request is currently signed or presigned
|
||||
func (v4 *signer) isRequestSigned() bool {
|
||||
if v4.isPresign && v4.Query.Get("X-Amz-Signature") != "" {
|
||||
return true
|
||||
}
|
||||
if v4.Request.Header.Get("Authorization") != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// unsign removes signing flags for both signed and presigned requests.
|
||||
func (v4 *signer) removePresign() {
|
||||
v4.Query.Del("X-Amz-Algorithm")
|
||||
v4.Query.Del("X-Amz-Signature")
|
||||
v4.Query.Del("X-Amz-Security-Token")
|
||||
v4.Query.Del("X-Amz-Date")
|
||||
v4.Query.Del("X-Amz-Expires")
|
||||
v4.Query.Del("X-Amz-Credential")
|
||||
v4.Query.Del("X-Amz-SignedHeaders")
|
||||
}
|
||||
|
||||
func makeHmac(key []byte, data []byte) []byte {
|
||||
hash := hmac.New(sha256.New, key)
|
||||
hash.Write(data)
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
|
||||
func makeSha256(data []byte) []byte {
|
||||
hash := sha256.New()
|
||||
hash.Write(data)
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
|
||||
func makeSha256Reader(reader io.ReadSeeker) []byte {
|
||||
hash := sha256.New()
|
||||
start, _ := reader.Seek(0, 1)
|
||||
defer reader.Seek(start, 0)
|
||||
|
||||
io.Copy(hash, reader)
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
5720
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/api.go
generated
vendored
Normal file
5720
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/api.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
169
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/api_object.go
generated
vendored
Normal file
169
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/api_object.go
generated
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AppendObjectInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// The name of the object.
|
||||
Key *string `location:"uri" locationName:"Key" type:"string" required:"true"`
|
||||
|
||||
// The starting position of the AppendObject operation.
|
||||
// When the AppendObject operation is successful, the x-kss-next-append-position header describes the starting position of the next operation.
|
||||
Position *int64 `location:"querystring" locationName:"position" type:"integer" required:"true"`
|
||||
|
||||
// The readable body payload to send to KS3.
|
||||
Body io.Reader `type:"blob"`
|
||||
|
||||
// The canned ACL to apply to the object.
|
||||
ACL *string `location:"header" locationName:"x-amz-acl" type:"string"`
|
||||
|
||||
// Specifies caching behavior along the request/reply chain.
|
||||
CacheControl *string `location:"header" locationName:"Cache-Control" type:"string"`
|
||||
|
||||
// Specifies presentational information for the object.
|
||||
ContentDisposition *string `location:"header" locationName:"Content-Disposition" type:"string"`
|
||||
|
||||
// Specifies what content encodings have been applied to the object and thus
|
||||
// what decoding mechanisms must be applied to obtain the media-type referenced
|
||||
// by the Content-Type header field.
|
||||
ContentEncoding *string `location:"header" locationName:"Content-Encoding" type:"string"`
|
||||
|
||||
// Size of the body in bytes. This parameter is useful when the size of the
|
||||
// body cannot be determined automatically.
|
||||
ContentLength *int64 `location:"header" locationName:"Content-Length" type:"integer"`
|
||||
|
||||
// Calculate MD5 value for message content (excluding header)
|
||||
ContentMD5 *string `location:"header" locationName:"Content-MD5" type:"string"`
|
||||
|
||||
// A standard MIME type describing the format of the object data.
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// When using Expect: 100-continue, the client will only send the request body after receiving confirmation from the server.
|
||||
// If the information in the request header is rejected, the client will not send the request body.
|
||||
Expect *string `location:"header" locationName:"Expect" type:"string"`
|
||||
|
||||
// The date and time at which the object is no longer cacheable.
|
||||
Expires *time.Time `location:"header" locationName:"Expires" type:"timestamp" timestampFormat:"rfc822"`
|
||||
|
||||
// A map of metadata to store with the object in S3.
|
||||
Metadata map[string]*string `location:"headers" locationName:"x-amz-meta-" type:"map"`
|
||||
|
||||
// The type of storage to use for the object. Defaults to 'STANDARD'.
|
||||
StorageClass *string `location:"header" locationName:"x-amz-storage-class" type:"string"`
|
||||
|
||||
// Set the maximum allowed size for a single addition of content
|
||||
ContentMaxLength *int64 `location:"header" locationName:"x-amz-content-maxlength" type:"integer"`
|
||||
|
||||
// Specifies the object tag of the object. Multiple tags can be set at the same time, such as: TagA=A&TagB=B.
|
||||
// Note: Key and Value need to be URL-encoded first. If an item does not have "=", the Value is considered to be an empty string.
|
||||
Tagging *string `location:"header" locationName:"x-amz-tagging" type:"string"`
|
||||
|
||||
// Allows grantee to read the object data and its metadata.
|
||||
GrantRead *string `location:"header" locationName:"x-amz-grant-read" type:"string"`
|
||||
|
||||
// Gives the grantee READ, READ_ACP, and WRITE_ACP permissions on the object.
|
||||
GrantFullControl *string `location:"header" locationName:"x-amz-grant-full-control" type:"string"`
|
||||
|
||||
// The Server-side encryption algorithm used when storing this object in KS3, eg: AES256.
|
||||
ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string"`
|
||||
|
||||
// Specifies the algorithm to use to when encrypting the object, eg: AES256.
|
||||
SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
|
||||
|
||||
// Specifies the customer-provided encryption key for KS3 to use in encrypting data.
|
||||
SSECustomerKey *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key" type:"string"`
|
||||
|
||||
// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
|
||||
SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
|
||||
|
||||
// Progress callback function
|
||||
ProgressFn aws.ProgressFunc `location:"function"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataAppendObjectInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataAppendObjectInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"Body"`
|
||||
}
|
||||
|
||||
type AppendObjectOutput struct {
|
||||
// Entity tag for the uploaded object.
|
||||
ETag *string `location:"header" locationName:"ETag" type:"string"`
|
||||
|
||||
// The position that should be provided for the next request, which is the size of the current object.
|
||||
NextAppendPosition *int64 `location:"header" locationName:"x-amz-next-append-position" type:"integer"`
|
||||
|
||||
// The type of Object.
|
||||
ObjectType *string `location:"header" locationName:"x-amz-object-type" type:"string"`
|
||||
|
||||
// The Server-side encryption algorithm used when storing this object in KS3, eg: AES256.
|
||||
ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string"`
|
||||
|
||||
// If server-side encryption with a customer-provided encryption key was requested,
|
||||
// the response will include this header confirming the encryption algorithm used.
|
||||
SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
|
||||
|
||||
// If server-side encryption with a customer-provided encryption key was requested,
|
||||
// the response will include this header to provide round trip message integrity
|
||||
// verification of the customer-provided encryption key.
|
||||
SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
|
||||
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataAppendObjectOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataAppendObjectOutput struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
// AppendObjectRequest generates a request for the AppendObject operation.
|
||||
func (c *S3) AppendObjectRequest(input *AppendObjectInput) (req *aws.Request, output *AppendObjectOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "AppendObject",
|
||||
HTTPMethod: "POST",
|
||||
HTTPPath: "/{Bucket}/{Key+}?append",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &AppendObjectInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
|
||||
if input.ProgressFn != nil {
|
||||
req.ProgressFn = input.ProgressFn
|
||||
}
|
||||
|
||||
output = &AppendObjectOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// AppendObject is used to append data to an Appendable object.
|
||||
func (c *S3) AppendObject(input *AppendObjectInput) (*AppendObjectOutput, error) {
|
||||
req, out := c.AppendObjectRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) AppendObjectWithContext(ctx aws.Context, input *AppendObjectInput) (*AppendObjectOutput, error) {
|
||||
req, out := c.AppendObjectRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
134
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/bucket_accessmonitor.go
generated
vendored
Normal file
134
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/bucket_accessmonitor.go
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
type PutBucketAccessMonitorInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Bucket access monitor configuration.
|
||||
AccessMonitorConfiguration *AccessMonitorConfiguration `locationName:"AccessMonitorConfiguration" type:"structure" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutBucketAccessMonitorInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutBucketAccessMonitorInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"AccessMonitorConfiguration"`
|
||||
}
|
||||
|
||||
type AccessMonitorConfiguration struct {
|
||||
// Specifies whether to enable access tracking for the bucket. The value range is as follows:
|
||||
// Enabled: After the bucket enables access tracking, the access tracking enable time is used as the default
|
||||
// last access time for all objects in the bucket.
|
||||
// Disabled: The access tracking status of the bucket can be changed to Disabled only when the bucket does not
|
||||
// have a lifecycle rule based on the last access time matching rule.
|
||||
Status *string `locationName:"Status" type:"string" required:"true"`
|
||||
}
|
||||
|
||||
type PutBucketAccessMonitorOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// PutBucketAccessMonitorRequest generates a request for the PutBucketAccessMonitor operation.
|
||||
func (c *S3) PutBucketAccessMonitorRequest(input *PutBucketAccessMonitorInput) (req *aws.Request, output *PutBucketAccessMonitorOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutBucketAccessMonitor",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?accessmonitor",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutBucketAccessMonitorInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &PutBucketAccessMonitorOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutBucketAccessMonitor sets bucket access monitor configuration.
|
||||
func (c *S3) PutBucketAccessMonitor(input *PutBucketAccessMonitorInput) (*PutBucketAccessMonitorOutput, error) {
|
||||
req, out := c.PutBucketAccessMonitorRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketAccessMonitorWithContext(ctx aws.Context, input *PutBucketAccessMonitorInput) (*PutBucketAccessMonitorOutput, error) {
|
||||
req, out := c.PutBucketAccessMonitorRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetBucketAccessMonitorInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetBucketAccessMonitorOutput struct {
|
||||
// Bucket access monitor configuration.
|
||||
AccessMonitorConfiguration *AccessMonitorConfiguration `locationName:"AccessMonitorConfiguration" type:"structure"`
|
||||
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetBucketAccessMonitorOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataGetBucketAccessMonitorOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"AccessMonitorConfiguration"`
|
||||
}
|
||||
|
||||
// GetBucketAccessMonitorRequest generates a request for the GetBucketAccessMonitor operation.
|
||||
func (c *S3) GetBucketAccessMonitorRequest(input *GetBucketAccessMonitorInput) (req *aws.Request, output *GetBucketAccessMonitorOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetBucketAccessMonitor",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?accessmonitor",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetBucketAccessMonitorInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &GetBucketAccessMonitorOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetBucketAccessMonitor gets bucket access monitor configuration.
|
||||
func (c *S3) GetBucketAccessMonitor(input *GetBucketAccessMonitorInput) (*GetBucketAccessMonitorOutput, error) {
|
||||
req, out := c.GetBucketAccessMonitorRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketAccessMonitorWithContext(ctx aws.Context, input *GetBucketAccessMonitorInput) (*GetBucketAccessMonitorOutput, error) {
|
||||
req, out := c.GetBucketAccessMonitorRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
194
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/bucket_encryption.go
generated
vendored
Normal file
194
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/bucket_encryption.go
generated
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
type PutBucketEncryptionInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Bucket encryption configuration container.
|
||||
ServerSideEncryptionConfiguration *ServerSideEncryptionConfiguration `locationName:"ServerSideEncryptionConfiguration" type:"structure" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutBucketEncryptionInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutBucketEncryptionInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"ServerSideEncryptionConfiguration"`
|
||||
|
||||
AutoFillMD5 bool
|
||||
}
|
||||
|
||||
type ServerSideEncryptionConfiguration struct {
|
||||
// Default encryption rule for bucket.
|
||||
Rule *BucketEncryptionRule `locationName:"Rule" type:"structure" required:"true"`
|
||||
}
|
||||
|
||||
type BucketEncryptionRule struct {
|
||||
// The child element of the default encryption configuration for the bucket.
|
||||
ApplyServerSideEncryptionByDefault *ApplyServerSideEncryptionByDefault `locationName:"ApplyServerSideEncryptionByDefault" type:"structure" required:"true"`
|
||||
}
|
||||
|
||||
type ApplyServerSideEncryptionByDefault struct {
|
||||
// The server-side encryption algorithm to be used by the bucket's default encryption configuration.
|
||||
SSEAlgorithm *string `locationName:"SSEAlgorithm" type:"string" required:"true"`
|
||||
}
|
||||
|
||||
type PutBucketEncryptionOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// PutBucketEncryptionRequest generates a request for the PutBucketEncryption operation.
|
||||
func (c *S3) PutBucketEncryptionRequest(input *PutBucketEncryptionInput) (req *aws.Request, output *PutBucketEncryptionOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutBucketEncryption",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?encryption",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutBucketEncryptionInput{}
|
||||
}
|
||||
|
||||
input.AutoFillMD5 = true
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &PutBucketEncryptionOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutBucketEncryption sets bucket encryption configuration.
|
||||
func (c *S3) PutBucketEncryption(input *PutBucketEncryptionInput) (*PutBucketEncryptionOutput, error) {
|
||||
req, out := c.PutBucketEncryptionRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketEncryptionWithContext(ctx aws.Context, input *PutBucketEncryptionInput) (*PutBucketEncryptionOutput, error) {
|
||||
req, out := c.PutBucketEncryptionRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetBucketEncryptionInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetBucketEncryptionOutput struct {
|
||||
// Bucket encryption configuration container.
|
||||
ServerSideEncryptionConfiguration *ServerSideEncryptionConfiguration `locationName:"ServerSideEncryptionConfiguration" type:"structure"`
|
||||
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetBucketEncryptionOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataGetBucketEncryptionOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"ServerSideEncryptionConfiguration"`
|
||||
}
|
||||
|
||||
// GetBucketEncryptionRequest generates a request for the GetBucketEncryption operation.
|
||||
func (c *S3) GetBucketEncryptionRequest(input *GetBucketEncryptionInput) (req *aws.Request, output *GetBucketEncryptionOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetBucketEncryption",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?encryption",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetBucketEncryptionInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &GetBucketEncryptionOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetBucketEncryption gets bucket encryption configuration.
|
||||
func (c *S3) GetBucketEncryption(input *GetBucketEncryptionInput) (*GetBucketEncryptionOutput, error) {
|
||||
req, out := c.GetBucketEncryptionRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketEncryptionWithContext(ctx aws.Context, input *GetBucketEncryptionInput) (*GetBucketEncryptionOutput, error) {
|
||||
req, out := c.GetBucketEncryptionRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type DeleteBucketEncryptionInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type DeleteBucketEncryptionOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// DeleteBucketEncryptionRequest generates a request for the DeleteBucketEncryption operation.
|
||||
func (c *S3) DeleteBucketEncryptionRequest(input *DeleteBucketEncryptionInput) (req *aws.Request, output *DeleteBucketEncryptionOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "DeleteBucketEncryption",
|
||||
HTTPMethod: "DELETE",
|
||||
HTTPPath: "/{Bucket}?encryption",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DeleteBucketEncryptionInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &DeleteBucketEncryptionOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteBucketEncryption deletes bucket encryption configuration.
|
||||
func (c *S3) DeleteBucketEncryption(input *DeleteBucketEncryptionInput) (*DeleteBucketEncryptionOutput, error) {
|
||||
req, out := c.DeleteBucketEncryptionRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) DeleteBucketEncryptionWithContext(ctx aws.Context, input *DeleteBucketEncryptionInput) (*DeleteBucketEncryptionOutput, error) {
|
||||
req, out := c.DeleteBucketEncryptionRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
27
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/bucket_location.go
generated
vendored
Normal file
27
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/bucket_location.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/awserr"
|
||||
"io"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var reBucketLocation = regexp.MustCompile(`>([^<>]+)<\/LocationConstraint`)
|
||||
|
||||
func buildGetBucketLocation(r *aws.Request) {
|
||||
if r.DataFilled() {
|
||||
out := r.Data.(*GetBucketLocationOutput)
|
||||
b, err := io.ReadAll(r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = awserr.New("Unmarshal",
|
||||
"failed reading response body", err)
|
||||
return
|
||||
}
|
||||
match := reBucketLocation.FindSubmatch(b)
|
||||
if len(match) > 1 {
|
||||
loc := string(match[1])
|
||||
out.LocationConstraint = aws.String(loc)
|
||||
}
|
||||
}
|
||||
}
|
||||
200
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/bucket_qos.go
generated
vendored
Normal file
200
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/bucket_qos.go
generated
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
type PutBucketQosInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Bucket flow control configuration container.
|
||||
BucketQosConfiguration *BucketQosConfiguration `locationName:"BucketQosConfiguration" type:"structure" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutBucketQosInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutBucketQosInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"BucketQosConfiguration"`
|
||||
}
|
||||
|
||||
type BucketQosConfiguration struct {
|
||||
// Set the bucket flow control quota.
|
||||
Quotas []*BucketQosQuota `locationName:"Quota" type:"list" flattened:"true" required:"true"`
|
||||
}
|
||||
|
||||
type BucketQosQuota struct {
|
||||
// Specify the storage medium type that needs flow control. Options: Extreme/Normal (default)
|
||||
// Extreme: SSD type storage medium
|
||||
// Normal (default): HDD type storage medium
|
||||
StorageMedium *string `locationName:"StorageMedium" type:"string"`
|
||||
|
||||
// External network upload bandwidth, in Gbps, the value must be a positive integer.
|
||||
ExtranetUploadBandwidth *int64 `locationName:"ExtranetUploadBandwidth" type:"integer"`
|
||||
|
||||
// Intranet network upload bandwidth, in Gbps, the value must be a positive integer.
|
||||
IntranetUploadBandwidth *int64 `locationName:"IntranetUploadBandwidth" type:"integer"`
|
||||
|
||||
// External network download bandwidth, in Gbps, the value must be a positive integer.
|
||||
ExtranetDownloadBandwidth *int64 `locationName:"ExtranetDownloadBandwidth" type:"integer"`
|
||||
|
||||
// Intranet network download bandwidth, in Gbps, the value must be a positive integer.
|
||||
IntranetDownloadBandwidth *int64 `locationName:"IntranetDownloadBandwidth" type:"integer"`
|
||||
}
|
||||
|
||||
type PutBucketQosOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// PutBucketQosRequest generates a request for the PutBucketQos operation.
|
||||
func (c *S3) PutBucketQosRequest(input *PutBucketQosInput) (req *aws.Request, output *PutBucketQosOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutBucketQos",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?bucketqos",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutBucketQosInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &PutBucketQosOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutBucketQos sets bucket flow control configuration.
|
||||
func (c *S3) PutBucketQos(input *PutBucketQosInput) (*PutBucketQosOutput, error) {
|
||||
req, out := c.PutBucketQosRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketQosWithContext(ctx aws.Context, input *PutBucketQosInput) (*PutBucketQosOutput, error) {
|
||||
req, out := c.PutBucketQosRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetBucketQosInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetBucketQosOutput struct {
|
||||
// Bucket flow control configuration container.
|
||||
BucketQosConfiguration *BucketQosConfiguration `locationName:"BucketQosConfiguration" type:"structure"`
|
||||
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetBucketQosOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataGetBucketQosOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"BucketQosConfiguration"`
|
||||
}
|
||||
|
||||
// GetBucketQosRequest generates a request for the GetBucketQos operation.
|
||||
func (c *S3) GetBucketQosRequest(input *GetBucketQosInput) (req *aws.Request, output *GetBucketQosOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetBucketQos",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?bucketqos",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetBucketQosInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &GetBucketQosOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetBucketQos gets bucket flow control configuration.
|
||||
func (c *S3) GetBucketQos(input *GetBucketQosInput) (*GetBucketQosOutput, error) {
|
||||
req, out := c.GetBucketQosRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketQosWithContext(ctx aws.Context, input *GetBucketQosInput) (*GetBucketQosOutput, error) {
|
||||
req, out := c.GetBucketQosRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type DeleteBucketQosInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type DeleteBucketQosOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// DeleteBucketQosRequest generates a request for the DeleteBucketQos operation.
|
||||
func (c *S3) DeleteBucketQosRequest(input *DeleteBucketQosInput) (req *aws.Request, output *DeleteBucketQosOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "DeleteBucketQos",
|
||||
HTTPMethod: "DELETE",
|
||||
HTTPPath: "/{Bucket}?bucketqos",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DeleteBucketQosInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &DeleteBucketQosOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteBucketQos deletes bucket flow control configuration.
|
||||
func (c *S3) DeleteBucketQos(input *DeleteBucketQosInput) (*DeleteBucketQosOutput, error) {
|
||||
req, out := c.DeleteBucketQosRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) DeleteBucketQosWithContext(ctx aws.Context, input *DeleteBucketQosInput) (*DeleteBucketQosOutput, error) {
|
||||
req, out := c.DeleteBucketQosRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
179
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/bucket_tagging.go
generated
vendored
Normal file
179
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/bucket_tagging.go
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
type PutBucketTaggingInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Bucket tagging configuration container.
|
||||
Tagging *Tagging `locationName:"Tagging" type:"structure" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutBucketTaggingInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutBucketTaggingInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"Tagging"`
|
||||
|
||||
AutoFillMD5 bool
|
||||
}
|
||||
|
||||
type PutBucketTaggingOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// PutBucketTaggingRequest generates a request for the PutBucketTagging operation.
|
||||
func (c *S3) PutBucketTaggingRequest(input *PutBucketTaggingInput) (req *aws.Request, output *PutBucketTaggingOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutBucketTagging",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?tagging",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutBucketTaggingInput{}
|
||||
}
|
||||
|
||||
input.AutoFillMD5 = true
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &PutBucketTaggingOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutBucketTagging sets bucket tagging configuration.
|
||||
func (c *S3) PutBucketTagging(input *PutBucketTaggingInput) (*PutBucketTaggingOutput, error) {
|
||||
req, out := c.PutBucketTaggingRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketTaggingWithContext(ctx aws.Context, input *PutBucketTaggingInput) (*PutBucketTaggingOutput, error) {
|
||||
req, out := c.PutBucketTaggingRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetBucketTaggingInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetBucketTaggingOutput struct {
|
||||
// Bucket tagging configuration container.
|
||||
Tagging *Tagging `locationName:"Tagging" type:"structure"`
|
||||
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetBucketTaggingOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataGetBucketTaggingOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"Tagging"`
|
||||
}
|
||||
|
||||
// GetBucketTaggingRequest generates a request for the GetBucketTagging operation.
|
||||
func (c *S3) GetBucketTaggingRequest(input *GetBucketTaggingInput) (req *aws.Request, output *GetBucketTaggingOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetBucketTagging",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?tagging",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetBucketTaggingInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &GetBucketTaggingOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetBucketTagging gets bucket tagging configuration.
|
||||
func (c *S3) GetBucketTagging(input *GetBucketTaggingInput) (*GetBucketTaggingOutput, error) {
|
||||
req, out := c.GetBucketTaggingRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketTaggingWithContext(ctx aws.Context, input *GetBucketTaggingInput) (*GetBucketTaggingOutput, error) {
|
||||
req, out := c.GetBucketTaggingRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type DeleteBucketTaggingInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type DeleteBucketTaggingOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// DeleteBucketTaggingRequest generates a request for the DeleteBucketTagging operation.
|
||||
func (c *S3) DeleteBucketTaggingRequest(input *DeleteBucketTaggingInput) (req *aws.Request, output *DeleteBucketTaggingOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "DeleteBucketTagging",
|
||||
HTTPMethod: "DELETE",
|
||||
HTTPPath: "/{Bucket}?tagging",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DeleteBucketTaggingInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &DeleteBucketTaggingOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteBucketTagging deletes bucket tagging configuration.
|
||||
func (c *S3) DeleteBucketTagging(input *DeleteBucketTaggingInput) (*DeleteBucketTaggingOutput, error) {
|
||||
req, out := c.DeleteBucketTaggingRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) DeleteBucketTaggingWithContext(ctx aws.Context, input *DeleteBucketTaggingInput) (*DeleteBucketTaggingOutput, error) {
|
||||
req, out := c.DeleteBucketTaggingRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
133
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/bucket_transfer_acceleration.go
generated
vendored
Normal file
133
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/bucket_transfer_acceleration.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
type PutBucketTransferAccelerationInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Bucket transfer acceleration configuration container.
|
||||
TransferAccelerationConfiguration *TransferAccelerationConfiguration `locationName:"TransferAccelerationConfiguration" type:"structure" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutBucketTransferAccelerationInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutBucketTransferAccelerationInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"TransferAccelerationConfiguration"`
|
||||
|
||||
AutoFillMD5 bool
|
||||
}
|
||||
|
||||
type TransferAccelerationConfiguration struct {
|
||||
// Whether the target bucket has enabled transfer acceleration.
|
||||
Enabled *bool `locationName:"Enabled" type:"boolean" required:"true"`
|
||||
}
|
||||
|
||||
type PutBucketTransferAccelerationOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// PutBucketTransferAccelerationRequest generates a request for the PutBucketTransferAcceleration operation.
|
||||
func (c *S3) PutBucketTransferAccelerationRequest(input *PutBucketTransferAccelerationInput) (req *aws.Request, output *PutBucketTransferAccelerationOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutBucketTransferAcceleration",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?transferAcceleration",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutBucketTransferAccelerationInput{}
|
||||
}
|
||||
|
||||
input.AutoFillMD5 = true
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &PutBucketTransferAccelerationOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutBucketTransferAcceleration sets bucket transfer acceleration configuration.
|
||||
func (c *S3) PutBucketTransferAcceleration(input *PutBucketTransferAccelerationInput) (*PutBucketTransferAccelerationOutput, error) {
|
||||
req, out := c.PutBucketTransferAccelerationRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketTransferAccelerationWithContext(ctx aws.Context, input *PutBucketTransferAccelerationInput) (*PutBucketTransferAccelerationOutput, error) {
|
||||
req, out := c.PutBucketTransferAccelerationRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetBucketTransferAccelerationInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetBucketTransferAccelerationOutput struct {
|
||||
// Bucket transfer acceleration configuration container.
|
||||
TransferAccelerationConfiguration *TransferAccelerationConfiguration `locationName:"TransferAccelerationConfiguration" type:"structure"`
|
||||
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetBucketTransferAccelerationOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataGetBucketTransferAccelerationOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"TransferAccelerationConfiguration"`
|
||||
}
|
||||
|
||||
// GetBucketTransferAccelerationRequest generates a request for the GetBucketTransferAcceleration operation.
|
||||
func (c *S3) GetBucketTransferAccelerationRequest(input *GetBucketTransferAccelerationInput) (req *aws.Request, output *GetBucketTransferAccelerationOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetBucketTransferAcceleration",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?transferAcceleration",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetBucketTransferAccelerationInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &GetBucketTransferAccelerationOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetBucketTransferAcceleration gets bucket transfer acceleration configuration.
|
||||
func (c *S3) GetBucketTransferAcceleration(input *GetBucketTransferAccelerationInput) (*GetBucketTransferAccelerationOutput, error) {
|
||||
req, out := c.GetBucketTransferAccelerationRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketTransferAccelerationWithContext(ctx aws.Context, input *GetBucketTransferAccelerationInput) (*GetBucketTransferAccelerationOutput, error) {
|
||||
req, out := c.GetBucketTransferAccelerationRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
520
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/checkpoint.go
generated
vendored
Normal file
520
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/checkpoint.go
generated
vendored
Normal file
@@ -0,0 +1,520 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/rest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultTaskNum int64 = 3
|
||||
|
||||
MaxPartNum int64 = 10000
|
||||
|
||||
MaxPartSize int64 = 5 * 1024 * 1024 * 1024
|
||||
|
||||
MinPartSize int64 = 100 * 1024
|
||||
|
||||
DefaultPartSize int64 = 5 * 1024 * 1024
|
||||
|
||||
FilePermMode = os.FileMode(0664)
|
||||
|
||||
DirPermMode = os.FileMode(0755)
|
||||
|
||||
CheckpointFileSuffixUploader = ".ucp"
|
||||
|
||||
CheckpointFileSuffixDownloader = ".dcp"
|
||||
|
||||
CheckpointFileSuffixCopier = ".ccp"
|
||||
|
||||
TempFileSuffix = ".temp"
|
||||
|
||||
CheckpointMagic = "B62CAE41-F268-4EC5-839D-FBE475E3FA02"
|
||||
)
|
||||
|
||||
// ------------------------------------ UploadCheckpoint ------------------------------------
|
||||
|
||||
type UploadCheckpoint struct {
|
||||
Magic string
|
||||
MD5 string
|
||||
CpFilePath string // checkpoint file full path
|
||||
UploadFilePath string // Local file path
|
||||
UploadFileSize int64 // Local file size
|
||||
UploadFileLastModified string // Local file last modified time
|
||||
BucketName string // Bucket name
|
||||
ObjectKey string // Object key
|
||||
PartSize int64 // Part size
|
||||
UploadId string // Upload ID
|
||||
PartETagList []*CompletedPart // Completed parts
|
||||
}
|
||||
|
||||
func newUploadCheckpoint(u *Uploader) (*UploadCheckpoint, error) {
|
||||
request := u.uploadFileRequest
|
||||
fileSize := aws.ToLong(request.FileSize)
|
||||
partSize := u.getPartSize(fileSize, aws.ToLong(request.PartSize))
|
||||
cp := &UploadCheckpoint{
|
||||
Magic: CheckpointMagic,
|
||||
UploadFileSize: fileSize,
|
||||
BucketName: aws.ToString(request.Bucket),
|
||||
ObjectKey: aws.ToString(request.Key),
|
||||
PartSize: partSize,
|
||||
PartETagList: make([]*CompletedPart, 0),
|
||||
}
|
||||
|
||||
filePath := aws.ToString(request.UploadFile)
|
||||
if filePath != "" {
|
||||
fileInfo, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cp.UploadFilePath = filePath
|
||||
cp.UploadFileLastModified = fileInfo.ModTime().String()
|
||||
} else {
|
||||
if request.ObjectMeta != nil {
|
||||
cp.UploadFileLastModified = aws.ToString(request.ObjectMeta[HTTPHeaderLastModified])
|
||||
}
|
||||
}
|
||||
|
||||
return cp, nil
|
||||
}
|
||||
|
||||
func generateUploadCpFilePath(request *UploadFileInput) (string, error) {
|
||||
name := fmt.Sprintf("%s/%s", *request.Bucket, *request.Key)
|
||||
md5Hash := md5.New()
|
||||
md5Hash.Write([]byte("ks3://" + rest.EscapePath(name, false)))
|
||||
destHash := hex.EncodeToString(md5Hash.Sum(nil))
|
||||
|
||||
filePath := aws.ToString(request.UploadFile)
|
||||
absPath, _ := filepath.Abs(filePath)
|
||||
md5Hash.Reset()
|
||||
md5Hash.Write([]byte(absPath))
|
||||
srcHash := hex.EncodeToString(md5Hash.Sum(nil))
|
||||
|
||||
var dir string
|
||||
baseDir := aws.ToString(request.CheckpointDir)
|
||||
if baseDir == "" {
|
||||
dir = os.TempDir()
|
||||
} else {
|
||||
dir = filepath.Dir(baseDir)
|
||||
}
|
||||
|
||||
cpFilePath := filepath.Join(dir, fmt.Sprintf("%v-%v%v", srcHash, destHash, CheckpointFileSuffixUploader))
|
||||
|
||||
return cpFilePath, nil
|
||||
}
|
||||
|
||||
// load checkpoint from local file
|
||||
func (cp *UploadCheckpoint) load() error {
|
||||
if cp.CpFilePath == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !FileExists(cp.CpFilePath) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 读取断点文件
|
||||
contents, err := os.ReadFile(cp.CpFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ucp := UploadCheckpoint{}
|
||||
if err = json.Unmarshal(contents, &ucp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 判断断点文件是否有效
|
||||
if !cp.isValid(ucp) {
|
||||
err := cp.remove()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 读取断点文件成功,将断点文件中的信息赋值给当前对象
|
||||
cp.UploadId = ucp.UploadId
|
||||
cp.PartETagList = ucp.PartETagList
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cp *UploadCheckpoint) isValid(ucp UploadCheckpoint) bool {
|
||||
md5sum := ucp.checksum()
|
||||
if CheckpointMagic != ucp.Magic || md5sum != ucp.MD5 {
|
||||
return false
|
||||
}
|
||||
|
||||
if cp.BucketName != ucp.BucketName ||
|
||||
cp.ObjectKey != ucp.ObjectKey ||
|
||||
cp.PartSize != ucp.PartSize ||
|
||||
cp.UploadFilePath != ucp.UploadFilePath ||
|
||||
cp.UploadFileSize != ucp.UploadFileSize ||
|
||||
cp.UploadFileLastModified != ucp.UploadFileLastModified {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(ucp.UploadId) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (cp *UploadCheckpoint) dump() error {
|
||||
if cp.CpFilePath == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
dir := filepath.Dir(cp.CpFilePath)
|
||||
if !DirExists(dir) {
|
||||
err := os.MkdirAll(dir, DirPermMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
cp.MD5 = cp.checksum()
|
||||
str, err := json.Marshal(cp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.WriteFile(cp.CpFilePath, str, FilePermMode)
|
||||
}
|
||||
|
||||
func (cp *UploadCheckpoint) checksum() string {
|
||||
str := cp.MD5
|
||||
cp.MD5 = ""
|
||||
json, _ := json.Marshal(cp)
|
||||
sum := md5.Sum(json)
|
||||
md5sum := hex.EncodeToString(sum[:])
|
||||
cp.MD5 = str
|
||||
return md5sum
|
||||
}
|
||||
|
||||
func (cp *UploadCheckpoint) remove() error {
|
||||
if cp.CpFilePath == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return os.Remove(cp.CpFilePath)
|
||||
}
|
||||
|
||||
// ------------------------------------ DownloadCheckpoint ------------------------------------
|
||||
|
||||
type DownloadCheckpoint struct {
|
||||
Magic string
|
||||
MD5 string
|
||||
CpFilePath string // checkpoint file full path
|
||||
DownloadFilePath string // Local file path
|
||||
BucketName string // Bucket name
|
||||
ObjectKey string // Object key
|
||||
ObjectSize int64 // Object size
|
||||
ObjectLastModified string // Object last modified
|
||||
PartSize int64 // Part size
|
||||
PartETagList []*CompletedPart // Completed parts
|
||||
}
|
||||
|
||||
func newDownloadCheckpoint(d *Downloader) (*DownloadCheckpoint, error) {
|
||||
request := d.downloadFileRequest
|
||||
meta := d.downloadFileMeta
|
||||
objectSize, _ := strconv.ParseInt(aws.ToString(meta[HTTPHeaderContentLength]), 10, 64)
|
||||
lastModified := aws.ToString(meta[HTTPHeaderLastModified])
|
||||
cp := &DownloadCheckpoint{
|
||||
Magic: CheckpointMagic,
|
||||
BucketName: aws.ToString(request.Bucket),
|
||||
ObjectKey: aws.ToString(request.Key),
|
||||
DownloadFilePath: aws.ToString(request.DownloadFile),
|
||||
ObjectSize: objectSize,
|
||||
ObjectLastModified: lastModified,
|
||||
PartSize: aws.ToLong(request.PartSize),
|
||||
PartETagList: make([]*CompletedPart, 0),
|
||||
}
|
||||
|
||||
return cp, nil
|
||||
}
|
||||
|
||||
func generateDownloadCpFilePath(request *DownloadFileInput) (string, error) {
|
||||
name := fmt.Sprintf("%v/%v", *request.Bucket, *request.Key)
|
||||
md5Hash := md5.New()
|
||||
md5Hash.Write([]byte("ks3://" + rest.EscapePath(name, false)))
|
||||
destHash := hex.EncodeToString(md5Hash.Sum(nil))
|
||||
|
||||
filePath := aws.ToString(request.DownloadFile)
|
||||
absPath, _ := filepath.Abs(filePath)
|
||||
md5Hash.Reset()
|
||||
md5Hash.Write([]byte(absPath))
|
||||
srcHash := hex.EncodeToString(md5Hash.Sum(nil))
|
||||
|
||||
var dir string
|
||||
baseDir := aws.ToString(request.CheckpointDir)
|
||||
if baseDir == "" {
|
||||
dir = os.TempDir()
|
||||
} else {
|
||||
dir = filepath.Dir(baseDir)
|
||||
}
|
||||
|
||||
cpFilePath := filepath.Join(dir, fmt.Sprintf("%v-%v%v", srcHash, destHash, CheckpointFileSuffixDownloader))
|
||||
|
||||
return cpFilePath, nil
|
||||
}
|
||||
|
||||
// load checkpoint from local file
|
||||
func (cp *DownloadCheckpoint) load() error {
|
||||
if cp.CpFilePath == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !FileExists(cp.CpFilePath) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 读取断点文件
|
||||
contents, err := os.ReadFile(cp.CpFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dcp := DownloadCheckpoint{}
|
||||
if err = json.Unmarshal(contents, &dcp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 判断断点文件是否有效
|
||||
if !cp.isValid(dcp) {
|
||||
cp.remove()
|
||||
return nil
|
||||
}
|
||||
|
||||
// 读取断点文件成功,将断点文件中的信息赋值给当前对象
|
||||
cp.PartETagList = dcp.PartETagList
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cp *DownloadCheckpoint) isValid(dcp DownloadCheckpoint) bool {
|
||||
md5sum := dcp.checksum()
|
||||
if CheckpointMagic != dcp.Magic || md5sum != dcp.MD5 {
|
||||
return false
|
||||
}
|
||||
|
||||
if cp.BucketName != dcp.BucketName ||
|
||||
cp.ObjectKey != dcp.ObjectKey ||
|
||||
cp.PartSize != dcp.PartSize ||
|
||||
cp.DownloadFilePath != dcp.DownloadFilePath ||
|
||||
cp.ObjectSize != dcp.ObjectSize ||
|
||||
cp.ObjectLastModified != dcp.ObjectLastModified {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (cp *DownloadCheckpoint) dump() error {
|
||||
if cp.CpFilePath == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
dir := filepath.Dir(cp.CpFilePath)
|
||||
if !DirExists(dir) {
|
||||
err := os.MkdirAll(dir, DirPermMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
cp.MD5 = cp.checksum()
|
||||
str, err := json.Marshal(cp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.WriteFile(cp.CpFilePath, str, FilePermMode)
|
||||
}
|
||||
|
||||
func (cp *DownloadCheckpoint) checksum() string {
|
||||
str := cp.MD5
|
||||
cp.MD5 = ""
|
||||
json, _ := json.Marshal(cp)
|
||||
sum := md5.Sum(json)
|
||||
md5sum := hex.EncodeToString(sum[:])
|
||||
cp.MD5 = str
|
||||
return md5sum
|
||||
}
|
||||
|
||||
func (cp *DownloadCheckpoint) remove() error {
|
||||
if cp.CpFilePath == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return os.Remove(cp.CpFilePath)
|
||||
}
|
||||
|
||||
// ------------------------------------ CopyCheckpoint ------------------------------------
|
||||
|
||||
type CopyCheckpoint struct {
|
||||
Magic string
|
||||
MD5 string
|
||||
CpFilePath string // checkpoint file full path
|
||||
BucketName string // Bucket name
|
||||
ObjectKey string // Object key
|
||||
SrcBucketName string // Source bucket name
|
||||
SrcObjectKey string // Source object key
|
||||
SrcObjectSize int64 // Source object size
|
||||
SrcObjectLastModified string // Source object last modified time
|
||||
PartSize int64 // Part size
|
||||
UploadId string // Upload ID
|
||||
PartETagList []*CompletedPart // Completed parts
|
||||
}
|
||||
|
||||
func newCopyCheckpoint(c *Copier) (*CopyCheckpoint, error) {
|
||||
request := c.copyFileRequest
|
||||
meta := c.copyObjectMeta
|
||||
|
||||
objectSize, _ := strconv.ParseInt(aws.ToString(meta[HTTPHeaderContentLength]), 10, 64)
|
||||
lastModified := aws.ToString(meta[HTTPHeaderLastModified])
|
||||
partSize := c.getPartSize(objectSize, aws.ToLong(request.PartSize))
|
||||
cp := &CopyCheckpoint{
|
||||
Magic: CheckpointMagic,
|
||||
BucketName: aws.ToString(request.Bucket),
|
||||
ObjectKey: aws.ToString(request.Key),
|
||||
SrcBucketName: aws.ToString(request.SourceBucket),
|
||||
SrcObjectKey: aws.ToString(request.SourceKey),
|
||||
SrcObjectSize: objectSize,
|
||||
SrcObjectLastModified: lastModified,
|
||||
PartSize: partSize,
|
||||
PartETagList: make([]*CompletedPart, 0),
|
||||
}
|
||||
|
||||
return cp, nil
|
||||
}
|
||||
|
||||
func generateCopyCpFilePath(request *CopyFileInput) (string, error) {
|
||||
dstName := fmt.Sprintf("%s/%s", *request.Bucket, *request.Key)
|
||||
md5Hash := md5.New()
|
||||
md5Hash.Write([]byte("ks3://" + rest.EscapePath(dstName, false)))
|
||||
destHash := hex.EncodeToString(md5Hash.Sum(nil))
|
||||
|
||||
srcName := fmt.Sprintf("%s/%s", *request.SourceBucket, *request.SourceKey)
|
||||
md5Hash.Reset()
|
||||
md5Hash.Write([]byte(srcName))
|
||||
srcHash := hex.EncodeToString(md5Hash.Sum(nil))
|
||||
|
||||
var dir string
|
||||
baseDir := aws.ToString(request.CheckpointDir)
|
||||
if baseDir == "" {
|
||||
dir = os.TempDir()
|
||||
} else {
|
||||
dir = filepath.Dir(baseDir)
|
||||
}
|
||||
|
||||
cpFilePath := filepath.Join(dir, fmt.Sprintf("%v-%v%v", srcHash, destHash, CheckpointFileSuffixCopier))
|
||||
|
||||
return cpFilePath, nil
|
||||
}
|
||||
|
||||
// load checkpoint from local file
|
||||
func (cp *CopyCheckpoint) load() error {
|
||||
if cp.CpFilePath == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !FileExists(cp.CpFilePath) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 读取断点文件
|
||||
contents, err := os.ReadFile(cp.CpFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ccp := CopyCheckpoint{}
|
||||
if err = json.Unmarshal(contents, &ccp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 判断断点文件是否有效
|
||||
if !cp.isValid(ccp) {
|
||||
err := cp.remove()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 读取断点文件成功,将断点文件中的信息赋值给当前对象
|
||||
cp.UploadId = ccp.UploadId
|
||||
cp.PartETagList = ccp.PartETagList
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cp *CopyCheckpoint) isValid(ccp CopyCheckpoint) bool {
|
||||
md5sum := ccp.checksum()
|
||||
if CheckpointMagic != ccp.Magic || md5sum != ccp.MD5 {
|
||||
return false
|
||||
}
|
||||
|
||||
if cp.BucketName != ccp.BucketName ||
|
||||
cp.ObjectKey != ccp.ObjectKey ||
|
||||
cp.SrcBucketName != ccp.SrcBucketName ||
|
||||
cp.SrcObjectKey != ccp.SrcObjectKey ||
|
||||
cp.SrcObjectSize != ccp.SrcObjectSize ||
|
||||
cp.SrcObjectLastModified != ccp.SrcObjectLastModified ||
|
||||
cp.PartSize != ccp.PartSize {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(ccp.UploadId) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (cp *CopyCheckpoint) dump() error {
|
||||
if cp.CpFilePath == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
dir := filepath.Dir(cp.CpFilePath)
|
||||
if !DirExists(dir) {
|
||||
err := os.MkdirAll(dir, DirPermMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
cp.MD5 = cp.checksum()
|
||||
str, err := json.Marshal(cp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.WriteFile(cp.CpFilePath, str, FilePermMode)
|
||||
}
|
||||
|
||||
func (cp *CopyCheckpoint) checksum() string {
|
||||
str := cp.MD5
|
||||
cp.MD5 = ""
|
||||
json, _ := json.Marshal(cp)
|
||||
sum := md5.Sum(json)
|
||||
md5sum := hex.EncodeToString(sum[:])
|
||||
cp.MD5 = str
|
||||
return md5sum
|
||||
}
|
||||
|
||||
func (cp *CopyCheckpoint) remove() error {
|
||||
if cp.CpFilePath == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return os.Remove(cp.CpFilePath)
|
||||
}
|
||||
97
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/const.go
generated
vendored
Normal file
97
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/const.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
package s3
|
||||
|
||||
// HTTP headers
|
||||
const (
|
||||
HTTPHeaderAcceptEncoding string = "Accept-Encoding"
|
||||
HTTPHeaderAuthorization = "Authorization"
|
||||
HTTPHeaderCacheControl = "Cache-Control"
|
||||
HTTPHeaderContentDisposition = "Content-Disposition"
|
||||
HTTPHeaderContentEncoding = "Content-Encoding"
|
||||
HTTPHeaderContentLength = "Content-Length"
|
||||
HTTPHeaderContentMD5 = "Content-MD5"
|
||||
HTTPHeaderContentType = "Content-Type"
|
||||
HTTPHeaderContentLanguage = "Content-Language"
|
||||
HTTPHeaderLastModified = "Last-Modified"
|
||||
HTTPHeaderDate = "Date"
|
||||
HTTPHeaderEtag = "Etag"
|
||||
HTTPHeaderExpires = "Expires"
|
||||
HTTPHeaderHost = "Host"
|
||||
HTTPHeaderAmzACL = "X-Amz-Acl"
|
||||
HTTPHeaderAmzChecksumCrc64ecma = "X-Amz-Checksum-Crc64ecma"
|
||||
HTTPHeaderAmzStorageClass = "X-Amz-Storage-Class"
|
||||
HTTPHeaderAmzDataRedundancyType = "X-Amz-Data-Redundancy-Type"
|
||||
HTTPHeaderAmzZRSSwitchEnable = "X-Amz-Zrs-Switch-Enable"
|
||||
HTTPHeaderAmzAllowSameActionOverlap = "X-Amz-Allow-Same-Action-Overlap"
|
||||
HTTPHeaderAmzBucketType = "X-Amz-Bucket-Type"
|
||||
HTTPHeaderAmzBucketVisitType = "X-Amz-Bucket-Visit-Type"
|
||||
)
|
||||
|
||||
// ACL
|
||||
const (
|
||||
ACLPrivate string = "private"
|
||||
ACLPublicRead string = "public-read"
|
||||
ACLPublicReadWrite string = "public-read-write"
|
||||
)
|
||||
|
||||
// StorageClass
|
||||
const (
|
||||
StorageClassExtremePL3 string = "EXTREME_PL3"
|
||||
StorageClassExtremePL2 string = "EXTREME_PL2"
|
||||
StorageClassExtremePL1 string = "EXTREME_PL1"
|
||||
StorageClassStandard string = "STANDARD"
|
||||
StorageClassIA string = "STANDARD_IA"
|
||||
StorageClassDeepIA string = "DEEP_IA"
|
||||
StorageClassArchive string = "ARCHIVE"
|
||||
StorageClassDeepColdArchive string = "DEEP_COLD_ARCHIVE"
|
||||
)
|
||||
|
||||
// BucketType
|
||||
const (
|
||||
BucketTypeExtremePL3 string = "EXTREME_PL3"
|
||||
BucketTypeExtremePL2 string = "EXTREME_PL2"
|
||||
BucketTypeExtremePL1 string = "EXTREME_PL1"
|
||||
BucketTypeNormal string = "NORMAL"
|
||||
BucketTypeIA string = "IA"
|
||||
BucketTypeDeepIA string = "DEEP_IA"
|
||||
BucketTypeArchive string = "ARCHIVE"
|
||||
)
|
||||
|
||||
const (
|
||||
BucketVisitTypeNormal string = "NORMAL"
|
||||
BucketVisitTypeFrequentList string = "FREQUENTLIST"
|
||||
)
|
||||
|
||||
type HTTPMethod string
|
||||
|
||||
const (
|
||||
PUT HTTPMethod = "PUT"
|
||||
GET HTTPMethod = "GET"
|
||||
DELETE HTTPMethod = "DELETE"
|
||||
HEAD HTTPMethod = "HEAD"
|
||||
POST HTTPMethod = "POST"
|
||||
)
|
||||
|
||||
const (
|
||||
AllUsersUri = "http://acs.amazonaws.com/groups/global/AllUsers"
|
||||
MetaPrefix = "x-amz-meta-"
|
||||
)
|
||||
|
||||
const (
|
||||
DataRedundancyTypeLRS string = "LRS"
|
||||
DataRedundancyTypeZRS string = "ZRS"
|
||||
)
|
||||
|
||||
const (
|
||||
StorageMediumNormal string = "Normal"
|
||||
StorageMediumExtreme string = "Extreme"
|
||||
)
|
||||
|
||||
const (
|
||||
AlgorithmAES256 string = "AES256"
|
||||
AlgorithmSM4 string = "SM4"
|
||||
)
|
||||
|
||||
const (
|
||||
StatusEnabled string = "Enabled"
|
||||
StatusDisabled string = "Disabled"
|
||||
)
|
||||
804
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/copier.go
generated
vendored
Normal file
804
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/copier.go
generated
vendored
Normal file
@@ -0,0 +1,804 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type CopyFileInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Object key of the object.
|
||||
Key *string `location:"uri" locationName:"Key" type:"string" required:"true"`
|
||||
|
||||
// The name of the source bucket.
|
||||
SourceBucket *string `location:"uri" locationName:"SourceBucket" type:"string" required:"true"`
|
||||
|
||||
// Object key of the source object.
|
||||
SourceKey *string `location:"uri" locationName:"SourceKey" type:"string" required:"true"`
|
||||
|
||||
// The size of each part.
|
||||
PartSize *int64 `type:"integer"`
|
||||
|
||||
// The number of tasks to upload the file.
|
||||
TaskNum *int64 `type:"integer"`
|
||||
|
||||
// Whether to enable checkpoint.
|
||||
EnableCheckpoint *bool `type:"boolean"`
|
||||
|
||||
// The directory to store the checkpoint file.
|
||||
CheckpointDir *string `type:"string"`
|
||||
|
||||
// The checkpoint file path.
|
||||
CheckpointFile *string `type:"string"`
|
||||
|
||||
// The canned ACL to apply to the object.
|
||||
ACL *string `location:"header" locationName:"x-amz-acl" type:"string"`
|
||||
|
||||
// Specifies caching behavior along the request/reply chain.
|
||||
CacheControl *string `location:"header" locationName:"Cache-Control" type:"string"`
|
||||
|
||||
// Specifies presentational information for the object.
|
||||
ContentDisposition *string `location:"header" locationName:"Content-Disposition" type:"string"`
|
||||
|
||||
// Specifies what content encodings have been applied to the object and thus
|
||||
// what decoding mechanisms must be applied to obtain the media-type referenced
|
||||
// by the Content-Type header field.
|
||||
ContentEncoding *string `location:"header" locationName:"Content-Encoding" type:"string"`
|
||||
|
||||
// A standard MIME type describing the format of the object data.
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// The date and time at which the object is no longer cacheable.
|
||||
Expires *time.Time `location:"header" locationName:"Expires" type:"timestamp" timestampFormat:"rfc822"`
|
||||
|
||||
// A map of metadata to store with the object in S3.
|
||||
Metadata map[string]*string `location:"headers" locationName:"x-amz-meta-" type:"map"`
|
||||
|
||||
// Specifies whether the metadata is copied from the source object or replaced
|
||||
// with metadata provided in the request.
|
||||
MetadataDirective *string `location:"header" locationName:"x-amz-metadata-directive" type:"string"`
|
||||
|
||||
// The type of storage to use for the object. Defaults to 'STANDARD'.
|
||||
StorageClass *string `location:"header" locationName:"x-amz-storage-class" type:"string"`
|
||||
|
||||
// Specifies the object tag of the object. Multiple tags can be set at the same time, such as: TagA=A&TagB=B.
|
||||
// Note: Key and Value need to be URL-encoded first. If an item does not have "=", the Value is considered to be an empty string.
|
||||
Tagging *string `location:"header" locationName:"x-amz-tagging" type:"string"`
|
||||
|
||||
// Specifies how to set the object tag of the target object.
|
||||
// Default value: COPY
|
||||
// Valid values:
|
||||
// COPY (default value): Copies the object tag of the source object to the target object.
|
||||
// REPLACE: Ignores the object tag of the source object and directly uses the object tag specified in the request.
|
||||
TaggingDirective *string `location:"header" locationName:"x-amz-tagging-directive" type:"string"`
|
||||
|
||||
// Specifies whether the object is forbidden to overwrite.
|
||||
ForbidOverwrite *bool `location:"header" locationName:"x-amz-forbid-overwrite" type:"boolean"`
|
||||
|
||||
// Allows grantee to read the object data and its metadata.
|
||||
GrantRead *string `location:"header" locationName:"x-amz-grant-read" type:"string"`
|
||||
|
||||
// Gives the grantee READ, READ_ACP, and WRITE_ACP permissions on the object.
|
||||
GrantFullControl *string `location:"header" locationName:"x-amz-grant-full-control" type:"string"`
|
||||
|
||||
// Copies the object if its entity tag (ETag) matches the specified tag.
|
||||
CopySourceIfMatch *string `location:"header" locationName:"x-amz-copy-source-if-match" type:"string"`
|
||||
|
||||
// Copies the object if it has been modified since the specified time.
|
||||
CopySourceIfModifiedSince *time.Time `location:"header" locationName:"x-amz-copy-source-if-modified-since" type:"timestamp" timestampFormat:"rfc822"`
|
||||
|
||||
// Copies the object if its entity tag (ETag) is different from the specified ETag.
|
||||
CopySourceIfNoneMatch *string `location:"header" locationName:"x-amz-copy-source-if-none-match" type:"string"`
|
||||
|
||||
// Copies the object if it hasn't been modified since the specified time.
|
||||
CopySourceIfUnmodifiedSince *time.Time `location:"header" locationName:"x-amz-copy-source-if-unmodified-since" type:"timestamp" timestampFormat:"rfc822"`
|
||||
|
||||
// Specifies the decryption algorithm used to decrypt the data source object. Valid value: AES256.
|
||||
CopySourceSSECustomerAlgorithm *string `location:"header" locationName:"x-amz-copy-source-server-side-encryption-customer-algorithm" type:"string"`
|
||||
|
||||
// The base64-encoded encryption key used for KS3 decryption specified by the user.
|
||||
// Its value must be the same as the key used when the data source object was created.
|
||||
CopySourceSSECustomerKey *string `location:"header" locationName:"x-amz-copy-source-server-side-encryption-customer-key" type:"string"`
|
||||
|
||||
// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
|
||||
// If the server encrypted with a user-provided encryption key, when decryption is requested,
|
||||
// the response will include this header to provide data consistency verification information
|
||||
// for the user-provided encryption key.
|
||||
CopySourceSSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-copy-source-server-side-encryption-customer-key-MD5" type:"string"`
|
||||
|
||||
// The Server-side encryption algorithm used when storing this object in KS3, eg: AES256.
|
||||
ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string"`
|
||||
|
||||
// Specifies the algorithm to use to when encrypting the object, eg: AES256.
|
||||
SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
|
||||
|
||||
// Specifies the customer-provided encryption key for KS3 to use in encrypting data.
|
||||
SSECustomerKey *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key" type:"string"`
|
||||
|
||||
// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
|
||||
SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
|
||||
|
||||
// Progress callback function
|
||||
ProgressFn aws.ProgressFunc `location:"function"`
|
||||
}
|
||||
|
||||
type CopyFileOutput struct {
|
||||
Bucket *string
|
||||
|
||||
Key *string
|
||||
|
||||
ETag *string
|
||||
|
||||
ChecksumCRC64ECMA *string
|
||||
}
|
||||
|
||||
func (c *S3) CopyFile(request *CopyFileInput) (*CopyFileOutput, error) {
|
||||
return c.CopyFileWithContext(context.Background(), request)
|
||||
}
|
||||
|
||||
func (c *S3) CopyFileWithContext(ctx context.Context, request *CopyFileInput) (*CopyFileOutput, error) {
|
||||
return newCopier(c, ctx, request).copyFile()
|
||||
}
|
||||
|
||||
func (c *S3) CopyFileAcrossRegion(request *CopyFileInput, dstClient *S3) (*UploadFileOutput, error) {
|
||||
return c.CopyFileAcrossRegionWithContext(context.Background(), request, dstClient)
|
||||
}
|
||||
|
||||
func (c *S3) CopyFileAcrossRegionWithContext(ctx context.Context, request *CopyFileInput, dstClient *S3) (*UploadFileOutput, error) {
|
||||
uploadFileRequest, err := c.buildUploadFileRequest(ctx, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dstClient.UploadFileWithContext(ctx, uploadFileRequest)
|
||||
}
|
||||
|
||||
func (c *S3) buildUploadFileRequest(ctx context.Context, request *CopyFileInput) (*UploadFileInput, error) {
|
||||
if request == nil {
|
||||
return nil, errors.New("copyFileRequest is required")
|
||||
}
|
||||
|
||||
if aws.ToString(request.Bucket) == "" {
|
||||
return nil, errors.New("bucket is required")
|
||||
}
|
||||
|
||||
if aws.ToString(request.Key) == "" {
|
||||
return nil, errors.New("key is required")
|
||||
}
|
||||
|
||||
if aws.ToString(request.SourceBucket) == "" {
|
||||
return nil, errors.New("source bucket is required")
|
||||
}
|
||||
|
||||
if aws.ToString(request.SourceKey) == "" {
|
||||
return nil, errors.New("source key is required")
|
||||
}
|
||||
|
||||
input := &UploadFileInput{
|
||||
Bucket: request.Bucket,
|
||||
Key: request.Key,
|
||||
PartSize: request.PartSize,
|
||||
TaskNum: request.TaskNum,
|
||||
EnableCheckpoint: request.EnableCheckpoint,
|
||||
CheckpointDir: request.CheckpointDir,
|
||||
CheckpointFile: request.CheckpointFile,
|
||||
ACL: request.ACL,
|
||||
CacheControl: request.CacheControl,
|
||||
ContentDisposition: request.ContentDisposition,
|
||||
ContentEncoding: request.ContentEncoding,
|
||||
ContentType: request.ContentType,
|
||||
Expires: request.Expires,
|
||||
Metadata: request.Metadata,
|
||||
StorageClass: request.StorageClass,
|
||||
Tagging: request.Tagging,
|
||||
ForbidOverwrite: request.ForbidOverwrite,
|
||||
GrantRead: request.GrantRead,
|
||||
GrantFullControl: request.GrantFullControl,
|
||||
ServerSideEncryption: request.ServerSideEncryption,
|
||||
SSECustomerAlgorithm: request.SSECustomerAlgorithm,
|
||||
SSECustomerKey: request.SSECustomerKey,
|
||||
SSECustomerKeyMD5: request.SSECustomerKeyMD5,
|
||||
ProgressFn: request.ProgressFn,
|
||||
}
|
||||
|
||||
fetcher := &Fetcher{
|
||||
client: c,
|
||||
request: request,
|
||||
}
|
||||
|
||||
var filePartFetcher FilePartFetcher = fetcher
|
||||
input.FilePartFetcher = &filePartFetcher
|
||||
|
||||
resp, err := c.HeadObject(&HeadObjectInput{
|
||||
Bucket: request.SourceBucket,
|
||||
Key: request.SourceKey,
|
||||
IfModifiedSince: request.CopySourceIfModifiedSince,
|
||||
IfUnmodifiedSince: request.CopySourceIfUnmodifiedSince,
|
||||
IfMatch: request.CopySourceIfMatch,
|
||||
IfNoneMatch: request.CopySourceIfNoneMatch,
|
||||
SSECustomerAlgorithm: request.CopySourceSSECustomerAlgorithm,
|
||||
SSECustomerKey: request.CopySourceSSECustomerKey,
|
||||
SSECustomerKeyMD5: request.CopySourceSSECustomerKeyMD5,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
input.ObjectMeta = resp.Metadata
|
||||
|
||||
if !strings.EqualFold(aws.ToString(request.MetadataDirective), "REPLACE") {
|
||||
input.CacheControl = resp.Metadata[HTTPHeaderCacheControl]
|
||||
input.ContentDisposition = resp.Metadata[HTTPHeaderContentDisposition]
|
||||
input.ContentEncoding = resp.Metadata[HTTPHeaderContentEncoding]
|
||||
input.ContentType = resp.Metadata[HTTPHeaderContentType]
|
||||
expires, err := time.Parse("Mon, 02 Jan 2006 15:04:05 GMT", aws.ToString(resp.Metadata[HTTPHeaderExpires]))
|
||||
if err == nil {
|
||||
input.Expires = aws.Time(expires)
|
||||
}
|
||||
|
||||
metaData := map[string]*string{}
|
||||
for k, v := range resp.Metadata {
|
||||
if strings.HasPrefix(strings.ToLower(k), MetaPrefix) {
|
||||
metaData[k] = v
|
||||
}
|
||||
}
|
||||
input.Metadata = metaData
|
||||
}
|
||||
if !strings.EqualFold(aws.ToString(request.TaggingDirective), "REPLACE") {
|
||||
taggingResp, err := c.GetObjectTaggingWithContext(ctx, &GetObjectTaggingInput{
|
||||
Bucket: request.SourceBucket,
|
||||
Key: request.SourceKey,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tagStr := taggingResp.Tagging.ToString()
|
||||
if tagStr != "" {
|
||||
input.Tagging = aws.String(tagStr)
|
||||
}
|
||||
}
|
||||
if input.ACL == nil {
|
||||
aclResp, err := c.GetObjectACLWithContext(ctx, &GetObjectACLInput{
|
||||
Bucket: request.SourceBucket,
|
||||
Key: request.SourceKey,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
input.ACL = aws.String(GetCannedACL(aclResp.Grants))
|
||||
}
|
||||
if input.StorageClass == nil {
|
||||
input.StorageClass = resp.Metadata[HTTPHeaderAmzStorageClass]
|
||||
}
|
||||
|
||||
return input, nil
|
||||
}
|
||||
|
||||
type Fetcher struct {
|
||||
client *S3
|
||||
request *CopyFileInput
|
||||
}
|
||||
|
||||
type Body struct {
|
||||
io.ReadCloser
|
||||
}
|
||||
|
||||
func (b *Body) Seek(offset int64, whence int) (int64, error) {
|
||||
return 0, os.ErrInvalid
|
||||
}
|
||||
|
||||
func (f *Fetcher) Fetch(objectRange []int64) (io.ReadSeeker, error) {
|
||||
resp, err := f.client.GetObject(&GetObjectInput{
|
||||
Bucket: f.request.SourceBucket,
|
||||
Key: f.request.SourceKey,
|
||||
Range: aws.String(fmt.Sprintf("bytes=%d-%d", objectRange[0], objectRange[1])),
|
||||
SSECustomerAlgorithm: f.request.CopySourceSSECustomerAlgorithm,
|
||||
SSECustomerKey: f.request.CopySourceSSECustomerKey,
|
||||
SSECustomerKeyMD5: f.request.CopySourceSSECustomerKeyMD5,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body := &Body{resp.Body}
|
||||
|
||||
return body, nil
|
||||
}
|
||||
|
||||
type Copier struct {
|
||||
client *S3
|
||||
|
||||
context context.Context
|
||||
|
||||
copyFileRequest *CopyFileInput
|
||||
|
||||
copyCheckpoint *CopyCheckpoint
|
||||
|
||||
CompletedSize int64
|
||||
|
||||
copyObjectMeta map[string]*string
|
||||
|
||||
mu sync.Mutex
|
||||
|
||||
error error
|
||||
}
|
||||
|
||||
func newCopier(s3 *S3, ctx context.Context, request *CopyFileInput) *Copier {
|
||||
return &Copier{
|
||||
client: s3,
|
||||
context: ctx,
|
||||
copyFileRequest: request,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Copier) copyFile() (*CopyFileOutput, error) {
|
||||
err := c.validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.copyObjectMeta, err = c.headObject()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fileSize, _ := strconv.ParseInt(aws.ToString(c.copyObjectMeta[HTTPHeaderContentLength]), 10, 64)
|
||||
|
||||
var resp *CopyFileOutput
|
||||
if fileSize <= aws.ToLong(c.copyFileRequest.PartSize) {
|
||||
resp, err = c.copyObject()
|
||||
} else {
|
||||
resp, err = c.multipartCopy()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.client.Config.CrcCheckEnabled {
|
||||
clientCrc64, _ := strconv.ParseUint(aws.ToString(c.copyObjectMeta[HTTPHeaderAmzChecksumCrc64ecma]), 10, 64)
|
||||
serverCrc64, _ := strconv.ParseUint(aws.ToString(resp.ChecksumCRC64ECMA), 10, 64)
|
||||
c.client.Config.LogDebug("check file crc64, client crc64:%d, server crc64:%d", clientCrc64, serverCrc64)
|
||||
if serverCrc64 != 0 && clientCrc64 != serverCrc64 {
|
||||
return nil, errors.New(fmt.Sprintf("crc64 check failed, client crc64:%d, server crc64:%d", clientCrc64, serverCrc64))
|
||||
}
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (c *Copier) validate() error {
|
||||
request := c.copyFileRequest
|
||||
if request == nil {
|
||||
return errors.New("copyFileRequest is required")
|
||||
}
|
||||
|
||||
if aws.ToString(request.Bucket) == "" {
|
||||
return errors.New("bucket is required")
|
||||
}
|
||||
|
||||
if aws.ToString(request.Key) == "" {
|
||||
return errors.New("key is required")
|
||||
}
|
||||
|
||||
if aws.ToString(request.SourceBucket) == "" {
|
||||
return errors.New("source bucket is required")
|
||||
}
|
||||
|
||||
if aws.ToString(request.SourceKey) == "" {
|
||||
return errors.New("source key is required")
|
||||
}
|
||||
|
||||
if request.PartSize == nil {
|
||||
request.PartSize = aws.Long(DefaultPartSize)
|
||||
} else if aws.ToLong(request.PartSize) < MinPartSize {
|
||||
request.PartSize = aws.Long(MinPartSize)
|
||||
} else if aws.ToLong(request.PartSize) > MaxPartSize {
|
||||
request.PartSize = aws.Long(MaxPartSize)
|
||||
}
|
||||
|
||||
if aws.ToLong(request.TaskNum) <= 0 {
|
||||
request.TaskNum = aws.Long(DefaultTaskNum)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Copier) copyObject() (*CopyFileOutput, error) {
|
||||
request := c.copyFileRequest
|
||||
input := &CopyObjectInput{
|
||||
Bucket: request.Bucket,
|
||||
Key: request.Key,
|
||||
SourceBucket: request.SourceBucket,
|
||||
SourceKey: request.SourceKey,
|
||||
ACL: request.ACL,
|
||||
CacheControl: request.CacheControl,
|
||||
ContentDisposition: request.ContentDisposition,
|
||||
ContentEncoding: request.ContentEncoding,
|
||||
ContentType: request.ContentType,
|
||||
Expires: request.Expires,
|
||||
Metadata: request.Metadata,
|
||||
MetadataDirective: request.MetadataDirective,
|
||||
StorageClass: request.StorageClass,
|
||||
Tagging: request.Tagging,
|
||||
TaggingDirective: request.TaggingDirective,
|
||||
ForbidOverwrite: request.ForbidOverwrite,
|
||||
GrantRead: request.GrantRead,
|
||||
GrantFullControl: request.GrantFullControl,
|
||||
CopySourceIfMatch: request.CopySourceIfMatch,
|
||||
CopySourceIfNoneMatch: request.CopySourceIfNoneMatch,
|
||||
CopySourceIfModifiedSince: request.CopySourceIfModifiedSince,
|
||||
CopySourceIfUnmodifiedSince: request.CopySourceIfUnmodifiedSince,
|
||||
CopySourceSSECustomerAlgorithm: request.CopySourceSSECustomerAlgorithm,
|
||||
CopySourceSSECustomerKey: request.CopySourceSSECustomerKey,
|
||||
CopySourceSSECustomerKeyMD5: request.CopySourceSSECustomerKeyMD5,
|
||||
ServerSideEncryption: request.ServerSideEncryption,
|
||||
SSECustomerAlgorithm: request.SSECustomerAlgorithm,
|
||||
SSECustomerKey: request.SSECustomerKey,
|
||||
SSECustomerKeyMD5: request.SSECustomerKeyMD5,
|
||||
}
|
||||
if c.copyFileRequest.StorageClass == nil {
|
||||
input.StorageClass = c.copyObjectMeta[HTTPHeaderAmzStorageClass]
|
||||
}
|
||||
|
||||
resp, err := c.client.CopyObjectWithContext(c.context, input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &CopyFileOutput{
|
||||
Bucket: request.Bucket,
|
||||
Key: request.Key,
|
||||
ETag: resp.CopyObjectResult.ETag,
|
||||
ChecksumCRC64ECMA: resp.CopyObjectResult.ChecksumCRC64ECMA,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Copier) multipartCopy() (*CopyFileOutput, error) {
|
||||
ccp, err := newCopyCheckpoint(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.copyCheckpoint = ccp
|
||||
|
||||
if aws.ToBoolean(c.copyFileRequest.EnableCheckpoint) {
|
||||
cpFilePath := aws.ToString(c.copyFileRequest.CheckpointFile)
|
||||
if cpFilePath == "" {
|
||||
cpFilePath, err = generateCopyCpFilePath(c.copyFileRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
ccp.CpFilePath = cpFilePath
|
||||
|
||||
err = c.copyCheckpoint.load()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ccp.UploadId != "" && !c.isUploadIdValid() {
|
||||
ccp.UploadId = ""
|
||||
ccp.PartETagList = make([]*CompletedPart, 0)
|
||||
ccp.remove()
|
||||
}
|
||||
}
|
||||
|
||||
if ccp.UploadId == "" {
|
||||
ccp.UploadId, err = c.initUploadId()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ccp.dump()
|
||||
}
|
||||
|
||||
fileSize := ccp.SrcObjectSize
|
||||
partSize := ccp.PartSize
|
||||
totalPartNum := (fileSize-1)/partSize + 1
|
||||
tasks := make(chan CopyPartTask, totalPartNum)
|
||||
|
||||
var i int64
|
||||
for i = 0; i < totalPartNum; i++ {
|
||||
partNum := i + 1
|
||||
offset := (partNum - 1) * partSize
|
||||
actualPartSize := c.getActualPartSize(fileSize, partSize, partNum)
|
||||
partETag := c.getPartETag(partNum)
|
||||
if partETag != nil {
|
||||
c.publishProgress(actualPartSize)
|
||||
} else {
|
||||
uploadPartTask := CopyPartTask{
|
||||
partNumber: partNum,
|
||||
offset: offset,
|
||||
actualPartSize: actualPartSize,
|
||||
}
|
||||
tasks <- uploadPartTask
|
||||
}
|
||||
}
|
||||
close(tasks)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for i = 0; i < aws.ToLong(c.copyFileRequest.TaskNum); i++ {
|
||||
wg.Add(1)
|
||||
go c.runTask(tasks, &wg)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
if c.error != nil {
|
||||
return nil, c.error
|
||||
}
|
||||
|
||||
completedMultipartUpload := c.getMultipartUploadParts()
|
||||
resp, err := c.completeMultipartUpload(completedMultipartUpload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.getCopyFileOutput(resp), nil
|
||||
}
|
||||
|
||||
func (c *Copier) getCopyFileOutput(resp *CompleteMultipartUploadOutput) *CopyFileOutput {
|
||||
return &CopyFileOutput{
|
||||
Bucket: resp.Bucket,
|
||||
Key: resp.Key,
|
||||
ETag: resp.ETag,
|
||||
ChecksumCRC64ECMA: resp.ChecksumCRC64ECMA,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Copier) getPartSize(fileSize int64, originPartSize int64) int64 {
|
||||
partSize := originPartSize
|
||||
totalPartNum := (fileSize-1)/partSize + 1
|
||||
for totalPartNum > MaxPartNum {
|
||||
partSize += originPartSize
|
||||
totalPartNum = (fileSize-1)/partSize + 1
|
||||
}
|
||||
return partSize
|
||||
}
|
||||
|
||||
func (c *Copier) getActualPartSize(fileSize int64, partSize int64, partNum int64) int64 {
|
||||
offset := (partNum - 1) * partSize
|
||||
actualPartSize := partSize
|
||||
if offset+partSize >= fileSize {
|
||||
actualPartSize = fileSize - offset
|
||||
}
|
||||
return actualPartSize
|
||||
}
|
||||
|
||||
func (c *Copier) getPartETag(partNumber int64) *CompletedPart {
|
||||
for _, partETag := range c.copyCheckpoint.PartETagList {
|
||||
if *partETag.PartNumber == partNumber {
|
||||
return partETag
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CopyPartTask struct {
|
||||
partNumber int64
|
||||
|
||||
offset int64
|
||||
|
||||
actualPartSize int64
|
||||
}
|
||||
|
||||
func (c *Copier) runTask(tasks <-chan CopyPartTask, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
for task := range tasks {
|
||||
if c.error != nil {
|
||||
return
|
||||
}
|
||||
|
||||
partETag, err := c.copyPart(task)
|
||||
if err != nil {
|
||||
c.setError(err)
|
||||
return
|
||||
}
|
||||
|
||||
c.updatePart(partETag)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Copier) copyPart(task CopyPartTask) (CompletedPart, error) {
|
||||
request := c.copyFileRequest
|
||||
ccp := c.copyCheckpoint
|
||||
var partETag CompletedPart
|
||||
|
||||
start := task.offset
|
||||
end := task.offset + task.actualPartSize - 1
|
||||
resp, err := c.client.UploadPartCopyWithContext(c.context, &UploadPartCopyInput{
|
||||
Bucket: aws.String(ccp.BucketName),
|
||||
Key: aws.String(ccp.ObjectKey),
|
||||
SourceBucket: aws.String(ccp.SrcBucketName),
|
||||
SourceKey: aws.String(ccp.SrcObjectKey),
|
||||
UploadID: aws.String(ccp.UploadId),
|
||||
PartNumber: aws.Long(task.partNumber),
|
||||
CopySourceRange: aws.String(fmt.Sprintf("bytes=%d-%d", start, end)),
|
||||
CopySourceIfMatch: request.CopySourceIfMatch,
|
||||
CopySourceIfNoneMatch: request.CopySourceIfNoneMatch,
|
||||
CopySourceIfModifiedSince: request.CopySourceIfModifiedSince,
|
||||
CopySourceIfUnmodifiedSince: request.CopySourceIfUnmodifiedSince,
|
||||
CopySourceSSECustomerAlgorithm: request.CopySourceSSECustomerAlgorithm,
|
||||
CopySourceSSECustomerKey: request.CopySourceSSECustomerKey,
|
||||
CopySourceSSECustomerKeyMD5: request.CopySourceSSECustomerKeyMD5,
|
||||
SSECustomerAlgorithm: request.SSECustomerAlgorithm,
|
||||
SSECustomerKey: request.SSECustomerKey,
|
||||
SSECustomerKeyMD5: request.SSECustomerKeyMD5,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return partETag, err
|
||||
}
|
||||
|
||||
partETag.PartNumber = aws.Long(task.partNumber)
|
||||
partETag.ETag = resp.CopyPartResult.ETag
|
||||
partETag.ChecksumCRC64ECMA = resp.CopyPartResult.ChecksumCRC64ECMA
|
||||
c.publishProgress(task.actualPartSize)
|
||||
|
||||
return partETag, nil
|
||||
}
|
||||
|
||||
func (c *Copier) updatePart(partETag CompletedPart) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
c.copyCheckpoint.PartETagList = append(c.copyCheckpoint.PartETagList, &partETag)
|
||||
c.copyCheckpoint.dump()
|
||||
}
|
||||
|
||||
func (c *Copier) setError(err error) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if c.error == nil {
|
||||
c.error = err
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Copier) getMultipartUploadParts() *CompletedMultipartUpload {
|
||||
partETags := c.copyCheckpoint.PartETagList
|
||||
// 按照PartNumber排序
|
||||
sort.Sort(CompletedParts(partETags))
|
||||
return &CompletedMultipartUpload{
|
||||
Parts: partETags,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Copier) completeMultipartUpload(completedMultipartUpload *CompletedMultipartUpload) (*CompleteMultipartUploadOutput, error) {
|
||||
resp, err := c.client.CompleteMultipartUploadWithContext(c.context, &CompleteMultipartUploadInput{
|
||||
Bucket: c.copyFileRequest.Bucket,
|
||||
Key: c.copyFileRequest.Key,
|
||||
UploadID: aws.String(c.copyCheckpoint.UploadId),
|
||||
MultipartUpload: completedMultipartUpload,
|
||||
ForbidOverwrite: c.copyFileRequest.ForbidOverwrite,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.copyCheckpoint.remove()
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (c *Copier) publishProgress(actualPartSize int64) {
|
||||
if c.copyFileRequest.ProgressFn != nil {
|
||||
atomic.AddInt64(&c.CompletedSize, actualPartSize)
|
||||
c.copyFileRequest.ProgressFn(actualPartSize, c.CompletedSize, c.copyCheckpoint.SrcObjectSize)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Copier) headObject() (map[string]*string, error) {
|
||||
request := c.copyFileRequest
|
||||
resp, err := c.client.HeadObjectWithContext(c.context, &HeadObjectInput{
|
||||
Bucket: request.SourceBucket,
|
||||
Key: request.SourceKey,
|
||||
IfModifiedSince: request.CopySourceIfModifiedSince,
|
||||
IfUnmodifiedSince: request.CopySourceIfUnmodifiedSince,
|
||||
IfMatch: request.CopySourceIfMatch,
|
||||
IfNoneMatch: request.CopySourceIfNoneMatch,
|
||||
SSECustomerAlgorithm: request.CopySourceSSECustomerAlgorithm,
|
||||
SSECustomerKey: request.CopySourceSSECustomerKey,
|
||||
SSECustomerKeyMD5: request.CopySourceSSECustomerKeyMD5,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Metadata, err
|
||||
}
|
||||
|
||||
func (c *Copier) initUploadId() (string, error) {
|
||||
request := c.copyFileRequest
|
||||
input := &CreateMultipartUploadInput{
|
||||
Bucket: request.Bucket,
|
||||
Key: request.Key,
|
||||
ACL: request.ACL,
|
||||
CacheControl: request.CacheControl,
|
||||
ContentDisposition: request.ContentDisposition,
|
||||
ContentEncoding: request.ContentEncoding,
|
||||
ContentType: request.ContentType,
|
||||
Expires: request.Expires,
|
||||
Metadata: request.Metadata,
|
||||
StorageClass: request.StorageClass,
|
||||
Tagging: request.Tagging,
|
||||
ForbidOverwrite: request.ForbidOverwrite,
|
||||
GrantRead: request.GrantRead,
|
||||
GrantFullControl: request.GrantFullControl,
|
||||
ServerSideEncryption: request.ServerSideEncryption,
|
||||
SSECustomerAlgorithm: request.SSECustomerAlgorithm,
|
||||
SSECustomerKey: request.SSECustomerKey,
|
||||
SSECustomerKeyMD5: request.SSECustomerKeyMD5,
|
||||
}
|
||||
if !strings.EqualFold(aws.ToString(request.MetadataDirective), "REPLACE") {
|
||||
input.CacheControl = c.copyObjectMeta[HTTPHeaderCacheControl]
|
||||
input.ContentDisposition = c.copyObjectMeta[HTTPHeaderContentDisposition]
|
||||
input.ContentEncoding = c.copyObjectMeta[HTTPHeaderContentEncoding]
|
||||
input.ContentType = c.copyObjectMeta[HTTPHeaderContentType]
|
||||
expires, err := time.Parse("Mon, 02 Jan 2006 15:04:05 GMT", aws.ToString(c.copyObjectMeta[HTTPHeaderExpires]))
|
||||
if err == nil {
|
||||
input.Expires = aws.Time(expires)
|
||||
}
|
||||
|
||||
metaData := map[string]*string{}
|
||||
for k, v := range c.copyObjectMeta {
|
||||
if strings.HasPrefix(strings.ToLower(k), MetaPrefix) {
|
||||
metaData[k] = v
|
||||
}
|
||||
}
|
||||
input.Metadata = metaData
|
||||
}
|
||||
if !strings.EqualFold(aws.ToString(request.TaggingDirective), "REPLACE") {
|
||||
taggingResp, err := c.client.GetObjectTaggingWithContext(c.context, &GetObjectTaggingInput{
|
||||
Bucket: request.SourceBucket,
|
||||
Key: request.SourceKey,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
tagStr := taggingResp.Tagging.ToString()
|
||||
if tagStr != "" {
|
||||
input.Tagging = aws.String(tagStr)
|
||||
}
|
||||
}
|
||||
if c.copyFileRequest.ACL == nil {
|
||||
aclResp, err := c.client.GetObjectACLWithContext(c.context, &GetObjectACLInput{
|
||||
Bucket: request.SourceBucket,
|
||||
Key: request.SourceKey,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
input.ACL = aws.String(GetCannedACL(aclResp.Grants))
|
||||
}
|
||||
if c.copyFileRequest.StorageClass == nil {
|
||||
input.StorageClass = c.copyObjectMeta[HTTPHeaderAmzStorageClass]
|
||||
}
|
||||
|
||||
resp, err := c.client.CreateMultipartUploadWithContext(c.context, input)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return aws.ToString(resp.UploadID), nil
|
||||
}
|
||||
|
||||
func (c *Copier) isUploadIdValid() bool {
|
||||
_, err := c.client.ListPartsWithContext(c.context, &ListPartsInput{
|
||||
Bucket: c.copyFileRequest.Bucket,
|
||||
Key: c.copyFileRequest.Key,
|
||||
UploadID: aws.String(c.copyCheckpoint.UploadId),
|
||||
})
|
||||
if err != nil && strings.Contains(err.Error(), "NoSuchUpload") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
196
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/cors.go
generated
vendored
Normal file
196
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/cors.go
generated
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
type PutBucketCORSInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
CORSConfiguration *CORSConfiguration `locationName:"CORSConfiguration" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/" `
|
||||
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutBucketCORSInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutBucketCORSInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"CORSConfiguration"`
|
||||
|
||||
AutoFillMD5 bool
|
||||
}
|
||||
|
||||
type CORSConfiguration struct {
|
||||
Rules []*CORSRule `locationName:"CORSRule" type:"list" flattened:"true"`
|
||||
|
||||
// Whether non-cross-domain requests return the Vary: Origin header.
|
||||
NonCrossOriginResponseVary *bool `locationName:"NonCrossOriginResponseVary" type:"boolean" xml:"NonCrossOriginResponseVary"`
|
||||
}
|
||||
|
||||
type CORSRule struct {
|
||||
AllowedHeaders []string `locationName:"AllowedHeader" type:"list" flattened:"true"`
|
||||
AllowedMethods []string `locationName:"AllowedMethod" type:"list" flattened:"true"`
|
||||
AllowedOrigins []string `locationName:"AllowedOrigin" type:"list" flattened:"true"`
|
||||
ExposeHeaders []string `locationName:"ExposeHeader" type:"list" flattened:"true"`
|
||||
MaxAgeSeconds *int64 `locationName:"MaxAgeSeconds"`
|
||||
}
|
||||
|
||||
type PutBucketCORSOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// PutBucketCORSRequest generates a request for the PutBucketCORS operation.
|
||||
func (c *S3) PutBucketCORSRequest(input *PutBucketCORSInput) (req *aws.Request, output *PutBucketCORSOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutBucketCors",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?cors",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutBucketCORSInput{}
|
||||
}
|
||||
|
||||
//目前默认为true
|
||||
input.AutoFillMD5 = true
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &PutBucketCORSOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutBucketCORS Sets the cors configuration for a bucket.
|
||||
func (c *S3) PutBucketCORS(input *PutBucketCORSInput) (*PutBucketCORSOutput, error) {
|
||||
req, out := c.PutBucketCORSRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketCORSWithContext(ctx aws.Context, input *PutBucketCORSInput) (*PutBucketCORSOutput, error) {
|
||||
req, out := c.PutBucketCORSRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetBucketCORSInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetBucketCORSOutput struct {
|
||||
CORSConfiguration *CORSConfiguration `locationName:"CORSConfiguration" type:"structure"`
|
||||
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetBucketCORSOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataGetBucketCORSOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"CORSConfiguration"`
|
||||
}
|
||||
|
||||
// GetBucketCORSRequest generates a request for the GetBucketCORS operation.
|
||||
func (c *S3) GetBucketCORSRequest(input *GetBucketCORSInput) (req *aws.Request, output *GetBucketCORSOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetBucketCors",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?cors",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetBucketCORSInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &GetBucketCORSOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetBucketCORS Returns the cors configuration for the bucket.
|
||||
func (c *S3) GetBucketCORS(input *GetBucketCORSInput) (*GetBucketCORSOutput, error) {
|
||||
req, out := c.GetBucketCORSRequest(input)
|
||||
err := req.Send()
|
||||
if req.Data != nil {
|
||||
out = req.Data.(*GetBucketCORSOutput)
|
||||
}
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketCORSWithContext(ctx aws.Context, input *GetBucketCORSInput) (*GetBucketCORSOutput, error) {
|
||||
req, out := c.GetBucketCORSRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
if req.Data != nil {
|
||||
out = req.Data.(*GetBucketCORSOutput)
|
||||
}
|
||||
return out, err
|
||||
}
|
||||
|
||||
type DeleteBucketCORSInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type DeleteBucketCORSOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// DeleteBucketCORSRequest generates a request for the DeleteBucketCORS operation.
|
||||
func (c *S3) DeleteBucketCORSRequest(input *DeleteBucketCORSInput) (req *aws.Request, output *DeleteBucketCORSOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "DeleteBucketCors",
|
||||
HTTPMethod: "DELETE",
|
||||
HTTPPath: "/{Bucket}?cors",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DeleteBucketCORSInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &DeleteBucketCORSOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteBucketCORS Deletes the cors configuration information set for the bucket.
|
||||
func (c *S3) DeleteBucketCORS(input *DeleteBucketCORSInput) (*DeleteBucketCORSOutput, error) {
|
||||
req, out := c.DeleteBucketCORSRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) DeleteBucketCORSWithContext(ctx aws.Context, input *DeleteBucketCORSInput) (*DeleteBucketCORSOutput, error) {
|
||||
req, out := c.DeleteBucketCORSRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
42
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/crc_check.go
generated
vendored
Normal file
42
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/crc_check.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/apierr"
|
||||
"hash"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func CheckUploadCrc64(r *aws.Request) {
|
||||
clientCrc := r.Crc64.Sum64()
|
||||
serverCrc := uint64(0)
|
||||
if r.HTTPResponse.Header.Get("X-Amz-Checksum-Crc64ecma") != "" {
|
||||
serverCrc, _ = strconv.ParseUint(r.HTTPResponse.Header.Get("X-Amz-Checksum-Crc64ecma"), 10, 64)
|
||||
}
|
||||
|
||||
r.Config.LogInfo("client crc:%d, server crc:%d", clientCrc, serverCrc)
|
||||
|
||||
if serverCrc != 0 && clientCrc != serverCrc {
|
||||
r.Error = apierr.New("CRCCheckError", fmt.Sprintf("client crc and server crc do not match, request id:[%s]", r.HTTPResponse.Header.Get("X-Kss-Request-Id")), nil)
|
||||
r.Config.LogError("%s", r.Error.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func CheckDownloadCrc64(s3 *S3, res *GetObjectOutput, crc hash.Hash64) error {
|
||||
var err error
|
||||
clientCrc := crc.Sum64()
|
||||
serverCrc := uint64(0)
|
||||
if res.Metadata["X-Amz-Checksum-Crc64ecma"] != nil {
|
||||
serverCrc, _ = strconv.ParseUint(*res.Metadata["X-Amz-Checksum-Crc64ecma"], 10, 64)
|
||||
}
|
||||
|
||||
s3.Config.LogInfo("client crc:%d, server crc:%d", clientCrc, serverCrc)
|
||||
|
||||
if serverCrc != 0 && clientCrc != serverCrc {
|
||||
err = apierr.New("CRCCheckError", fmt.Sprintf("client crc and server crc do not match, request id:[%s]", *res.Metadata["X-Kss-Request-Id"]), nil)
|
||||
s3.Config.LogError("%s", err.Error())
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
126
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/data_redundancy_switch.go
generated
vendored
Normal file
126
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/data_redundancy_switch.go
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PutBucketDataRedundancySwitchInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
// The bucket data redundancy type.
|
||||
// Valid value: LRS丨ZRS
|
||||
// LRS: local redundancy storage
|
||||
// ZRS: zone redundancy storage
|
||||
DataRedundancyType *string `location:"header" locationName:"x-amz-data-redundancy-type" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type PutBucketDataRedundancySwitchOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// PutBucketDataRedundancySwitchRequest generates a request for the PutBucketDataRedundancySwitch operation.
|
||||
func (c *S3) PutBucketDataRedundancySwitchRequest(input *PutBucketDataRedundancySwitchInput) (req *aws.Request, output *PutBucketDataRedundancySwitchOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutBucketDataRedundancySwitch",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?dataRedundancySwitch",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutBucketDataRedundancySwitchInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &PutBucketDataRedundancySwitchOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutBucketDataRedundancySwitch sets the data redundancy type for the bucket.
|
||||
func (c *S3) PutBucketDataRedundancySwitch(input *PutBucketDataRedundancySwitchInput) (*PutBucketDataRedundancySwitchOutput, error) {
|
||||
req, out := c.PutBucketDataRedundancySwitchRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketDataRedundancySwitchWithContext(ctx aws.Context, input *PutBucketDataRedundancySwitchInput) (*PutBucketDataRedundancySwitchOutput, error) {
|
||||
req, out := c.PutBucketDataRedundancySwitchRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetBucketDataRedundancySwitchInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetBucketDataRedundancySwitchOutput struct {
|
||||
// The bucket data redundancy switch configuration.
|
||||
DataRedundancySwitch *DataRedundancySwitch `locationName:"DataRedundancySwitch" type:"structure"`
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetBucketDataRedundancySwitchOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type DataRedundancySwitch struct {
|
||||
// The bucket data redundancy type.
|
||||
DataRedundancyType *string `locationName:"DataRedundancyType" type:"string"`
|
||||
// Time when zone redundancy is enabled.
|
||||
SwitchTime *time.Time `locationName:"SwitchTime" type:"timestamp" timestampFormat:"iso8601"`
|
||||
}
|
||||
|
||||
type metadataGetBucketDataRedundancySwitchOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"DataRedundancySwitch"`
|
||||
}
|
||||
|
||||
// GetBucketDataRedundancySwitchRequest generates a request for the GetBucketDataRedundancySwitch operation.
|
||||
func (c *S3) GetBucketDataRedundancySwitchRequest(input *GetBucketDataRedundancySwitchInput) (req *aws.Request, output *GetBucketDataRedundancySwitchOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetBucketDataRedundancySwitch",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?dataRedundancySwitch",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetBucketDataRedundancySwitchInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &GetBucketDataRedundancySwitchOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetBucketDataRedundancySwitch gets the data redundancy switch configuration for the bucket.
|
||||
func (c *S3) GetBucketDataRedundancySwitch(input *GetBucketDataRedundancySwitchInput) (*GetBucketDataRedundancySwitchOutput, error) {
|
||||
req, out := c.GetBucketDataRedundancySwitchRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketDataRedundancySwitchWithContext(ctx aws.Context, input *GetBucketDataRedundancySwitchInput) (*GetBucketDataRedundancySwitchOutput, error) {
|
||||
req, out := c.GetBucketDataRedundancySwitchRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
219
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/decompresspolicy.go
generated
vendored
Normal file
219
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/decompresspolicy.go
generated
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
package s3
|
||||
|
||||
import "github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
|
||||
// PutBucketDecompressPolicyRequest generates a request for the PutBucketDecompressPolicy operation.
|
||||
func (c *S3) PutBucketDecompressPolicyRequest(input *PutBucketDecompressPolicyInput) (req *aws.Request, output *PutBucketDecompressPolicyOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutBucketDecompressPolicy",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?decompresspolicy",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutBucketDecompressPolicyInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
req.ContentType = "application/json"
|
||||
output = &PutBucketDecompressPolicyOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutBucketDecompressPolicy sets the decompression policy for the bucket.
|
||||
func (c *S3) PutBucketDecompressPolicy(input *PutBucketDecompressPolicyInput) (*PutBucketDecompressPolicyOutput, error) {
|
||||
req, out := c.PutBucketDecompressPolicyRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketDecompressPolicyWithContext(ctx aws.Context, input *PutBucketDecompressPolicyInput) (*PutBucketDecompressPolicyOutput, error) {
|
||||
req, out := c.PutBucketDecompressPolicyRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type PutBucketDecompressPolicyInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
BucketDecompressPolicy *BucketDecompressPolicy `locationName:"BucketDecompressPolicy" type:"structure"`
|
||||
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutBucketDecompressPolicyInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutBucketDecompressPolicyInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"BucketDecompressPolicy"`
|
||||
}
|
||||
|
||||
type BucketDecompressPolicy struct {
|
||||
Rules []*DecompressPolicyRule `json:"rules,omitempty" type:"list" locationName:"rules" required:"true"`
|
||||
}
|
||||
|
||||
type DecompressPolicyRule struct {
|
||||
// The name of the decompression strategy and the unique identifier of the decompression rule configured by the bucket. Value range: [1, 256].
|
||||
// Description: The length is 1-256 characters and can only be composed of uppercase or lowercase English letters, numbers, underscores (_), and hyphens (-).
|
||||
Id *string `json:"id,omitempty" type:"string" locationName:"id" required:"true"`
|
||||
|
||||
// ZIP online decompression trigger event, currently supports the following operations:
|
||||
// "ObjectCreated:*": represents all operations for creating objects, including Put, Post, Copy objects, and merging segmentation tasks;
|
||||
// "ObjectCreated:Put": Use the Put method to upload a ZIP package;
|
||||
// "ObjectCreated:Post": Use the Post method to upload a ZIP package;
|
||||
// "ObjectCreated:Copy": Use the Copy method to copy a ZIP package;
|
||||
// "ObjectCreated:CompleteMultipartUpload": Use merge to upload ZIP packages in chunks.
|
||||
Events *string `json:"events,omitempty" type:"string" locationName:"events" required:"true"`
|
||||
|
||||
// Match rule prefix (ZIP package that matches the prefix).
|
||||
// If no prefix is specified, all ZIP packages uploaded will be matched by default.
|
||||
Prefix *string `json:"prefix,omitempty" type:"string" locationName:"prefix"`
|
||||
|
||||
// Match rule suffix.
|
||||
// The default is. zip, and currently only supports ZIP package format.
|
||||
Suffix []*string `json:"suffix,omitempty" type:"list" locationName:"suffix" required:"true"`
|
||||
|
||||
// The processing method for files with the same name after decompression is not to overwrite them by default
|
||||
// The parameter values are as follows:
|
||||
// 0 (default value): Do not overwrite skip, keep existing objects in the bucket, skip objects with the same name, do not decompress;
|
||||
// 1: Overwrite, preserve the extracted object, and delete any existing objects with the same name in the bucket.
|
||||
Overwrite *int64 `json:"overwrite,omitempty" type:"integer" locationName:"overwrite" required:"true"`
|
||||
|
||||
// The address for task callback, URL address.
|
||||
Callback *string `json:"callback,omitempty" type:"string" locationName:"callback"`
|
||||
|
||||
// Task callback format, JSON format (required if callback address is set).
|
||||
CallbackFormat *string `json:"callback_format,omitempty" type:"string" locationName:"callback_format"`
|
||||
|
||||
// Specify the prefix of the output file in the target bucket after decompression. If it is not empty, it must end with a '/'.
|
||||
// If left blank, it will be saved by default in the root path of the storage bucket.
|
||||
PathPrefix *string `json:"path_prefix,omitempty" type:"string" locationName:"path_prefix"`
|
||||
|
||||
// Specify whether the compressed file path requires a compressed file name, with the following parameter values:
|
||||
// 0 (default): Keep compressed file name
|
||||
// 1: Extract directly to the target directory
|
||||
PathPrefixReplaced *int64 `json:"path_prefix_replaced,omitempty" type:"integer" locationName:"path_prefix_replaced"`
|
||||
|
||||
// Type of file decompression strategy.
|
||||
// Fixed value: decompress.
|
||||
PolicyType *string `json:"policy_type,omitempty" type:"string" locationName:"policy_type" required:"true"`
|
||||
}
|
||||
|
||||
type PutBucketDecompressPolicyOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// GetBucketDecompressPolicyRequest generates a request for the GetBucketDecompressPolicy operation.
|
||||
func (c *S3) GetBucketDecompressPolicyRequest(input *GetBucketDecompressPolicyInput) (req *aws.Request, output *GetBucketDecompressPolicyOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetBucketDecompressPolicy",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?decompresspolicy",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetBucketDecompressPolicyInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
req.ContentType = "application/json"
|
||||
output = &GetBucketDecompressPolicyOutput{
|
||||
BucketDecompressPolicy: &BucketDecompressPolicy{},
|
||||
}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetBucketDecompressPolicy gets the decompression policy for the bucket.
|
||||
func (c *S3) GetBucketDecompressPolicy(input *GetBucketDecompressPolicyInput) (*GetBucketDecompressPolicyOutput, error) {
|
||||
req, out := c.GetBucketDecompressPolicyRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketDecompressPolicyWithContext(ctx aws.Context, input *GetBucketDecompressPolicyInput) (*GetBucketDecompressPolicyOutput, error) {
|
||||
req, out := c.GetBucketDecompressPolicyRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetBucketDecompressPolicyInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetBucketDecompressPolicyOutput struct {
|
||||
BucketDecompressPolicy *BucketDecompressPolicy `locationName:"BucketDecompressPolicy" type:"structure"`
|
||||
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetBucketDecompressPolicyOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataGetBucketDecompressPolicyOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"BucketDecompressPolicy"`
|
||||
}
|
||||
|
||||
// DeleteBucketDecompressPolicyRequest generates a request for the DeleteBucketDecompressPolicy operation.
|
||||
func (c *S3) DeleteBucketDecompressPolicyRequest(input *DeleteBucketDecompressPolicyInput) (req *aws.Request, output *DeleteBucketDecompressPolicyOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "DeleteBucketDecompressPolicy",
|
||||
HTTPMethod: "DELETE",
|
||||
HTTPPath: "/{Bucket}?decompresspolicy",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DeleteBucketDecompressPolicyInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &DeleteBucketDecompressPolicyOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteBucketDecompressPolicy deletes the decompression policy for the bucket.
|
||||
func (c *S3) DeleteBucketDecompressPolicy(input *DeleteBucketDecompressPolicyInput) (*DeleteBucketDecompressPolicyOutput, error) {
|
||||
req, out := c.DeleteBucketDecompressPolicyRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) DeleteBucketDecompressPolicyWithContext(ctx aws.Context, input *DeleteBucketDecompressPolicyInput) (*DeleteBucketDecompressPolicyOutput, error) {
|
||||
req, out := c.DeleteBucketDecompressPolicyRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type DeleteBucketDecompressPolicyInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
type DeleteBucketDecompressPolicyOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
542
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/downloader.go
generated
vendored
Normal file
542
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/downloader.go
generated
vendored
Normal file
@@ -0,0 +1,542 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/crc"
|
||||
"hash"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type DownloadFileInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Object key of the object.
|
||||
Key *string `location:"uri" locationName:"Key" type:"string" required:"true"`
|
||||
|
||||
// The path of the file to be downloaded.
|
||||
DownloadFile *string `type:"string" locationName:"DownloadFile" required:"true"`
|
||||
|
||||
// The size of each part.
|
||||
PartSize *int64 `type:"integer" locationName:"PartSize"`
|
||||
|
||||
// The number of tasks to download the file.
|
||||
TaskNum *int64 `type:"integer" locationName:"TaskNum"`
|
||||
|
||||
// Whether to enable checkpoint.
|
||||
EnableCheckpoint *bool `type:"boolean" locationName:"EnableCheckpoint"`
|
||||
|
||||
// The directory to store the checkpoint file.
|
||||
CheckpointDir *string `type:"string" locationName:"CheckpointDir"`
|
||||
|
||||
// The checkpoint file path.
|
||||
CheckpointFile *string `type:"string" locationName:"CheckpointFile"`
|
||||
|
||||
// 下载的范围,range[0]为开始位置,range[1]为结束位置
|
||||
// range[0] 小于 0 时表示从文件头开始下载
|
||||
// range[1] 小于 0 时表示下载到文件末尾
|
||||
// range[0] 和 range[1] 都小于 0 时表示下载整个文件
|
||||
// range[0] 和 range[1] 都大于等于 0 时表示下载指定范围的文件
|
||||
// range[0] 大于 range[1] 且 range[1] 非负时表示下载整个文件
|
||||
// 例如:
|
||||
// range=[0, 99] 表示下载文件的前100个字节
|
||||
// range=[100, 199] 表示下载文件的第101个字节至第200个字节
|
||||
// range=[100, -1] 表示下载文件的第101个字节至文件末尾
|
||||
// range=[-1, 100] 表示下载文件的后100个字节
|
||||
// Downloads the specified range bytes of an object.
|
||||
Range []int64 `locationName:"Range" type:"list"`
|
||||
|
||||
// Sets the Content-Type header of the response.
|
||||
ResponseContentType *string `location:"querystring" locationName:"response-content-type" type:"string"`
|
||||
|
||||
// Sets the Content-Language header of the response.
|
||||
ResponseContentLanguage *string `location:"querystring" locationName:"response-content-language" type:"string"`
|
||||
|
||||
// Sets the Expires header of the response.
|
||||
ResponseExpires *time.Time `location:"querystring" locationName:"response-expires" type:"timestamp" timestampFormat:"iso8601"`
|
||||
|
||||
// Sets the Cache-Control header of the response.
|
||||
ResponseCacheControl *string `location:"querystring" locationName:"response-cache-control" type:"string"`
|
||||
|
||||
// Sets the Content-Disposition header of the response
|
||||
ResponseContentDisposition *string `location:"querystring" locationName:"response-content-disposition" type:"string"`
|
||||
|
||||
// Sets the Content-Encoding header of the response.
|
||||
ResponseContentEncoding *string `location:"querystring" locationName:"response-content-encoding" type:"string"`
|
||||
|
||||
// Return the object only if it has been modified since the specified time,
|
||||
// otherwise return a 304 (not modified).
|
||||
IfModifiedSince *time.Time `location:"header" locationName:"If-Modified-Since" type:"timestamp" timestampFormat:"rfc822"`
|
||||
|
||||
// Return the object only if it has not been modified since the specified time,
|
||||
// otherwise return a 412 (precondition failed).
|
||||
IfUnmodifiedSince *time.Time `location:"header" locationName:"If-Unmodified-Since" type:"timestamp" timestampFormat:"rfc822"`
|
||||
|
||||
// Return the object only if its entity tag (ETag) is the same as the one specified,
|
||||
// otherwise return a 412 (precondition failed).
|
||||
IfMatch *string `location:"header" locationName:"If-Match" type:"string"`
|
||||
|
||||
// Return the object only if its entity tag (ETag) is different from the one
|
||||
// specified, otherwise return a 304 (not modified).
|
||||
IfNoneMatch *string `location:"header" locationName:"If-None-Match" type:"string"`
|
||||
|
||||
// Specify the encoding type of the client.
|
||||
// If you want to compress and transmit the returned content using gzip,
|
||||
// you need to add a request header: Accept-Encoding:gzip。
|
||||
// KS3 will determine whether to return gzip compressed data based on the
|
||||
// Content-Type and Object size (not less than 1 KB) of the object.
|
||||
// Value: gzip、br、deflate
|
||||
AcceptEncoding *string `location:"header" locationName:"Accept-Encoding" type:"string"`
|
||||
|
||||
// Specifies the algorithm to use to when encrypting the object, eg: AES256.
|
||||
SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
|
||||
|
||||
// Specifies the customer-provided encryption key for KS3 to use in encrypting data.
|
||||
SSECustomerKey *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key" type:"string"`
|
||||
|
||||
// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
|
||||
SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
|
||||
|
||||
// Progress callback function
|
||||
ProgressFn aws.ProgressFunc `location:"function"`
|
||||
}
|
||||
|
||||
type DownloadFileOutput struct {
|
||||
Bucket *string
|
||||
|
||||
Key *string
|
||||
|
||||
ETag *string
|
||||
|
||||
ChecksumCRC64ECMA *string
|
||||
|
||||
ObjectMeta map[string]*string
|
||||
}
|
||||
|
||||
func (c *S3) DownloadFile(request *DownloadFileInput) (*DownloadFileOutput, error) {
|
||||
return c.DownloadFileWithContext(context.Background(), request)
|
||||
}
|
||||
|
||||
func (c *S3) DownloadFileWithContext(ctx context.Context, request *DownloadFileInput) (*DownloadFileOutput, error) {
|
||||
return newDownloader(c, ctx, request).downloadFile()
|
||||
}
|
||||
|
||||
type Downloader struct {
|
||||
client *S3
|
||||
|
||||
context context.Context
|
||||
|
||||
downloadFileRequest *DownloadFileInput
|
||||
|
||||
downloadCheckpoint *DownloadCheckpoint
|
||||
|
||||
CompletedSize int64
|
||||
|
||||
downloadFileSize int64
|
||||
|
||||
downloadFileMeta map[string]*string
|
||||
|
||||
mu sync.Mutex
|
||||
|
||||
error error
|
||||
}
|
||||
|
||||
func newDownloader(s3 *S3, ctx context.Context, request *DownloadFileInput) *Downloader {
|
||||
return &Downloader{
|
||||
client: s3,
|
||||
context: ctx,
|
||||
downloadFileRequest: request,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Downloader) downloadFile() (*DownloadFileOutput, error) {
|
||||
err := d.validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d.downloadFileMeta, err = d.headObject()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dcp, err := newDownloadCheckpoint(d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d.downloadCheckpoint = dcp
|
||||
|
||||
if aws.ToBoolean(d.downloadFileRequest.EnableCheckpoint) {
|
||||
cpFilePath := aws.ToString(d.downloadFileRequest.CheckpointFile)
|
||||
if cpFilePath == "" {
|
||||
cpFilePath, err = generateDownloadCpFilePath(d.downloadFileRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
dcp.CpFilePath = cpFilePath
|
||||
|
||||
err = dcp.load()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !FileExists(dcp.DownloadFilePath + TempFileSuffix) {
|
||||
dcp.PartETagList = make([]*CompletedPart, 0)
|
||||
dcp.remove()
|
||||
}
|
||||
}
|
||||
|
||||
err = d.createDownloadDir(dcp.DownloadFilePath + TempFileSuffix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
objectRange := d.getObjectRange()
|
||||
d.downloadFileSize = objectRange[1] - objectRange[0] + 1
|
||||
partSize := aws.ToLong(d.downloadFileRequest.PartSize)
|
||||
totalPartNum := (d.downloadFileSize-1)/partSize + 1
|
||||
tasks := make(chan DownloadPartTask, totalPartNum)
|
||||
|
||||
var i int64
|
||||
for i = 0; i < totalPartNum; i++ {
|
||||
partNum := i + 1
|
||||
start := objectRange[0] + i*partSize
|
||||
end := Min(start+partSize-1, objectRange[1])
|
||||
actualPartSize := end - start + 1
|
||||
if d.getPartETag(partNum) != nil {
|
||||
d.publishProgress(actualPartSize)
|
||||
} else {
|
||||
downloadPartTask := DownloadPartTask{
|
||||
partNumber: partNum,
|
||||
start: start,
|
||||
end: end,
|
||||
actualPartSize: actualPartSize,
|
||||
}
|
||||
tasks <- downloadPartTask
|
||||
}
|
||||
}
|
||||
close(tasks)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for i = 0; i < aws.ToLong(d.downloadFileRequest.TaskNum); i++ {
|
||||
wg.Add(1)
|
||||
go d.runTask(tasks, &wg)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
if d.error != nil {
|
||||
return nil, d.error
|
||||
}
|
||||
|
||||
if d.downloadFileRequest.Range == nil && d.client.Config.CrcCheckEnabled {
|
||||
clientCrc64 := d.getCrc64Ecma(dcp.PartETagList)
|
||||
serverCrc64, _ := strconv.ParseUint(aws.ToString(d.downloadFileMeta[HTTPHeaderAmzChecksumCrc64ecma]), 10, 64)
|
||||
d.client.Config.LogDebug("check file crc64, client crc64:%d, server crc64:%d", clientCrc64, serverCrc64)
|
||||
if serverCrc64 != 0 && clientCrc64 != serverCrc64 {
|
||||
return nil, errors.New(fmt.Sprintf("crc64 check failed, client crc64:%d, server crc64:%d", clientCrc64, serverCrc64))
|
||||
}
|
||||
}
|
||||
|
||||
err = d.complete()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return d.getDownloadFileOutput(), nil
|
||||
}
|
||||
|
||||
func (d *Downloader) validate() error {
|
||||
request := d.downloadFileRequest
|
||||
if request == nil {
|
||||
return errors.New("download file request is required")
|
||||
}
|
||||
|
||||
if aws.ToString(request.Bucket) == "" {
|
||||
return errors.New("bucket is required")
|
||||
}
|
||||
|
||||
if aws.ToString(request.Key) == "" {
|
||||
return errors.New("key is required")
|
||||
}
|
||||
|
||||
err := d.normalizeDownloadPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if request.PartSize == nil {
|
||||
request.PartSize = aws.Long(DefaultPartSize)
|
||||
} else if aws.ToLong(request.PartSize) < MinPartSize {
|
||||
request.PartSize = aws.Long(MinPartSize)
|
||||
} else if aws.ToLong(request.PartSize) > MaxPartSize {
|
||||
request.PartSize = aws.Long(MaxPartSize)
|
||||
}
|
||||
|
||||
if aws.ToLong(request.TaskNum) <= 0 {
|
||||
request.TaskNum = aws.Long(DefaultTaskNum)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Downloader) getDownloadFileOutput() *DownloadFileOutput {
|
||||
return &DownloadFileOutput{
|
||||
Bucket: d.downloadFileRequest.Bucket,
|
||||
Key: d.downloadFileRequest.Key,
|
||||
ETag: d.downloadFileMeta[HTTPHeaderEtag],
|
||||
ChecksumCRC64ECMA: d.downloadFileMeta[HTTPHeaderAmzChecksumCrc64ecma],
|
||||
ObjectMeta: d.downloadFileMeta,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Downloader) getActualPartSize(fileSize int64, partSize int64, partNum int64) int64 {
|
||||
offset := (partNum - 1) * partSize
|
||||
actualPartSize := partSize
|
||||
if offset+partSize >= fileSize {
|
||||
actualPartSize = fileSize - offset
|
||||
}
|
||||
return actualPartSize
|
||||
}
|
||||
|
||||
func (d *Downloader) getPartETag(partNumber int64) *CompletedPart {
|
||||
for _, partETag := range d.downloadCheckpoint.PartETagList {
|
||||
if *partETag.PartNumber == partNumber {
|
||||
return partETag
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DownloadPartTask struct {
|
||||
partNumber int64
|
||||
|
||||
actualPartSize int64
|
||||
|
||||
start int64
|
||||
|
||||
end int64
|
||||
}
|
||||
|
||||
func (d *Downloader) runTask(tasks <-chan DownloadPartTask, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
for task := range tasks {
|
||||
if d.error != nil {
|
||||
return
|
||||
}
|
||||
|
||||
partETag, err := d.downloadPart(task)
|
||||
if err != nil {
|
||||
d.setError(err)
|
||||
return
|
||||
}
|
||||
|
||||
d.updatePart(partETag)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Downloader) downloadPart(task DownloadPartTask) (CompletedPart, error) {
|
||||
request := d.downloadFileRequest
|
||||
dcp := d.downloadCheckpoint
|
||||
tempFilePath := dcp.DownloadFilePath + TempFileSuffix
|
||||
var completedPart CompletedPart
|
||||
resp, err := d.client.GetObjectWithContext(d.context, &GetObjectInput{
|
||||
Bucket: aws.String(dcp.BucketName),
|
||||
Key: aws.String(dcp.ObjectKey),
|
||||
Range: aws.String(fmt.Sprintf("bytes=%d-%d", task.start, task.end)),
|
||||
ResponseContentType: request.ResponseContentType,
|
||||
ResponseContentLanguage: request.ResponseContentLanguage,
|
||||
ResponseExpires: request.ResponseExpires,
|
||||
ResponseCacheControl: request.ResponseCacheControl,
|
||||
ResponseContentDisposition: request.ResponseContentDisposition,
|
||||
ResponseContentEncoding: request.ResponseContentEncoding,
|
||||
IfModifiedSince: request.IfModifiedSince,
|
||||
IfUnmodifiedSince: request.IfUnmodifiedSince,
|
||||
IfMatch: request.IfMatch,
|
||||
IfNoneMatch: request.IfNoneMatch,
|
||||
AcceptEncoding: request.AcceptEncoding,
|
||||
SSECustomerAlgorithm: request.SSECustomerAlgorithm,
|
||||
SSECustomerKey: request.SSECustomerKey,
|
||||
SSECustomerKeyMD5: request.SSECustomerKeyMD5,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return completedPart, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var crc64 hash.Hash64
|
||||
crc64 = crc.NewCRC(crc.CrcTable(), 0)
|
||||
resp.Body = aws.TeeReader(resp.Body, crc64, task.actualPartSize, nil)
|
||||
|
||||
fd, err := os.OpenFile(tempFilePath, os.O_WRONLY|os.O_CREATE, FilePermMode)
|
||||
if err != nil {
|
||||
return completedPart, err
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
_, err = fd.Seek((task.partNumber-1)*dcp.PartSize, io.SeekStart)
|
||||
if err != nil {
|
||||
return completedPart, err
|
||||
}
|
||||
|
||||
_, err = io.Copy(fd, resp.Body)
|
||||
if err != nil {
|
||||
return completedPart, err
|
||||
}
|
||||
|
||||
completedPart.PartNumber = aws.Long(task.partNumber)
|
||||
completedPart.ChecksumCRC64ECMA = aws.String(strconv.FormatUint(crc64.Sum64(), 10))
|
||||
d.publishProgress(task.actualPartSize)
|
||||
|
||||
return completedPart, nil
|
||||
}
|
||||
|
||||
func (d *Downloader) updatePart(partETag CompletedPart) {
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
|
||||
d.downloadCheckpoint.PartETagList = append(d.downloadCheckpoint.PartETagList, &partETag)
|
||||
d.downloadCheckpoint.dump()
|
||||
}
|
||||
|
||||
func (d *Downloader) setError(err error) {
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
|
||||
if d.error == nil {
|
||||
d.error = err
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Downloader) publishProgress(actualPartSize int64) {
|
||||
if d.downloadFileRequest.ProgressFn != nil {
|
||||
atomic.AddInt64(&d.CompletedSize, actualPartSize)
|
||||
d.downloadFileRequest.ProgressFn(actualPartSize, d.CompletedSize, d.downloadFileSize)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Downloader) getCrc64Ecma(parts []*CompletedPart) uint64 {
|
||||
if parts == nil || len(parts) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
sort.Sort(CompletedParts(d.downloadCheckpoint.PartETagList))
|
||||
|
||||
crcTemp, _ := strconv.ParseUint(*parts[0].ChecksumCRC64ECMA, 10, 64)
|
||||
for i := 1; i < len(parts); i++ {
|
||||
crc2, _ := strconv.ParseUint(*parts[i].ChecksumCRC64ECMA, 10, 64)
|
||||
partSize := d.getActualPartSize(d.downloadFileSize, aws.ToLong(d.downloadFileRequest.PartSize), *parts[i].PartNumber)
|
||||
crcTemp = crc.CRC64Combine(crcTemp, crc2, (uint64)(partSize))
|
||||
}
|
||||
|
||||
return crcTemp
|
||||
}
|
||||
|
||||
func (d *Downloader) complete() error {
|
||||
fileName := aws.ToString(d.downloadFileRequest.DownloadFile)
|
||||
tempFileName := fileName + TempFileSuffix
|
||||
err := os.Rename(tempFileName, fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.downloadCheckpoint.remove()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Downloader) headObject() (map[string]*string, error) {
|
||||
request := d.downloadFileRequest
|
||||
resp, err := d.client.HeadObjectWithContext(d.context, &HeadObjectInput{
|
||||
Bucket: request.Bucket,
|
||||
Key: request.Key,
|
||||
IfModifiedSince: request.IfModifiedSince,
|
||||
IfUnmodifiedSince: request.IfUnmodifiedSince,
|
||||
IfMatch: request.IfMatch,
|
||||
IfNoneMatch: request.IfNoneMatch,
|
||||
SSECustomerAlgorithm: request.SSECustomerAlgorithm,
|
||||
SSECustomerKey: request.SSECustomerKey,
|
||||
SSECustomerKeyMD5: request.SSECustomerKeyMD5,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Metadata, err
|
||||
}
|
||||
|
||||
func (d *Downloader) createDownloadDir(filePath string) error {
|
||||
dir := filepath.Dir(filePath)
|
||||
if !DirExists(dir) {
|
||||
err := os.MkdirAll(dir, DirPermMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Downloader) getObjectRange() []int64 {
|
||||
objectRange := d.downloadFileRequest.Range
|
||||
objectSize := d.downloadCheckpoint.ObjectSize
|
||||
if objectRange == nil {
|
||||
return []int64{0, objectSize - 1}
|
||||
}
|
||||
|
||||
if !d.isValidRange(objectRange, objectSize) {
|
||||
d.client.Config.LogWarn("Invalid range value: %v, ignore it and request for entire object", objectRange)
|
||||
return []int64{0, objectSize - 1}
|
||||
}
|
||||
objectStart := objectRange[0]
|
||||
objectEnd := objectRange[1]
|
||||
|
||||
if objectStart < 0 {
|
||||
return []int64{objectSize - objectEnd, objectSize - 1}
|
||||
}
|
||||
|
||||
if objectEnd < 0 {
|
||||
return []int64{objectStart, objectSize - 1}
|
||||
}
|
||||
|
||||
return []int64{objectStart, Min(objectEnd, objectSize-1)}
|
||||
}
|
||||
|
||||
func (d *Downloader) isValidRange(objectRange []int64, objectSize int64) bool {
|
||||
if len(objectRange) != 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
objectStart := objectRange[0]
|
||||
objectEnd := objectRange[1]
|
||||
|
||||
if objectStart < 0 && objectEnd < 0 || objectEnd >= 0 && objectStart > objectEnd {
|
||||
return false
|
||||
}
|
||||
|
||||
return objectStart < objectSize
|
||||
}
|
||||
|
||||
func (d *Downloader) normalizeDownloadPath() error {
|
||||
downloadPath := aws.ToString(d.downloadFileRequest.DownloadFile)
|
||||
if downloadPath == "" {
|
||||
downloadPath = aws.ToString(d.downloadFileRequest.Key)
|
||||
}
|
||||
// 规范化路径
|
||||
normalizedPath := filepath.Clean(downloadPath)
|
||||
// 获取绝对路径
|
||||
absPath, err := filepath.Abs(normalizedPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.downloadFileRequest.DownloadFile = aws.String(absPath)
|
||||
|
||||
return nil
|
||||
}
|
||||
60
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/errors.go
generated
vendored
Normal file
60
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/errors.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package s3
|
||||
|
||||
const (
|
||||
|
||||
// ErrCodeBucketAlreadyExists for service response error code
|
||||
// "BucketAlreadyExists".
|
||||
//
|
||||
// The requested bucket name is not available. The bucket namespace is shared
|
||||
// by all users of the system. Select a different name and try again.
|
||||
ErrCodeBucketAlreadyExists = "BucketAlreadyExists"
|
||||
|
||||
// ErrCodeBucketAlreadyOwnedByYou for service response error code
|
||||
// "BucketAlreadyOwnedByYou".
|
||||
//
|
||||
// The bucket you tried to create already exists, and you own it. Amazon S3
|
||||
// returns this error in all AWS Regions except in the North Virginia Region.
|
||||
// For legacy compatibility, if you re-create an existing bucket that you already
|
||||
// own in the North Virginia Region, Amazon S3 returns 200 OK and resets the
|
||||
// bucket access control lists (ACLs).
|
||||
ErrCodeBucketAlreadyOwnedByYou = "BucketAlreadyOwnedByYou"
|
||||
|
||||
// ErrCodeInvalidObjectState for service response error code
|
||||
// "InvalidObjectState".
|
||||
//
|
||||
// Object is archived and inaccessible until restored.
|
||||
ErrCodeInvalidObjectState = "InvalidObjectState"
|
||||
|
||||
// ErrCodeNoSuchBucket for service response error code
|
||||
// "NoSuchBucket".
|
||||
//
|
||||
// The specified bucket does not exist.
|
||||
ErrCodeNoSuchBucket = "NoSuchBucket"
|
||||
|
||||
// ErrCodeNoSuchKey for service response error code
|
||||
// "NoSuchKey".
|
||||
//
|
||||
// The specified key does not exist.
|
||||
ErrCodeNoSuchKey = "NoSuchKey"
|
||||
|
||||
// ErrCodeNoSuchUpload for service response error code
|
||||
// "NoSuchUpload".
|
||||
//
|
||||
// The specified multipart upload does not exist.
|
||||
ErrCodeNoSuchUpload = "NoSuchUpload"
|
||||
|
||||
// ErrCodeObjectAlreadyInActiveTierError for service response error code
|
||||
// "ObjectAlreadyInActiveTierError".
|
||||
//
|
||||
// This action is not allowed against this storage tier.
|
||||
ErrCodeObjectAlreadyInActiveTierError = "ObjectAlreadyInActiveTierError"
|
||||
|
||||
// ErrCodeObjectNotInActiveTierError for service response error code
|
||||
// "ObjectNotInActiveTierError".
|
||||
//
|
||||
// The source object of the COPY action is not in the active tier and is only
|
||||
// stored in Amazon S3 Glacier.
|
||||
ErrCodeObjectNotInActiveTierError = "ObjectNotInActiveTierError"
|
||||
)
|
||||
53
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/host_style_bucket.go
generated
vendored
Normal file
53
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/host_style_bucket.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/awsutil"
|
||||
)
|
||||
|
||||
var reDomain = regexp.MustCompile(`^[a-z0-9][a-z0-9\.\-\_]{1,61}[a-z0-9]$`)
|
||||
var reIPAddress = regexp.MustCompile(`^(\d+\.){3}\d+$`)
|
||||
|
||||
// dnsCompatibleBucketName returns true if the bucket name is DNS compatible.
|
||||
// Buckets created outside the classic region MUST be DNS compatible.
|
||||
func dnsCompatibleBucketName(bucket string) bool {
|
||||
return reDomain.MatchString(bucket) &&
|
||||
!reIPAddress.MatchString(bucket) &&
|
||||
!strings.Contains(bucket, "..")
|
||||
}
|
||||
|
||||
// hostStyleBucketName returns true if the request should put the bucket in
|
||||
// the host. This is false if S3ForcePathStyle is explicitly set or if the
|
||||
// bucket is not DNS compatible.
|
||||
func hostStyleBucketName(r *aws.Request, bucket string) bool {
|
||||
if r.Config.S3ForcePathStyle {
|
||||
return false
|
||||
}
|
||||
|
||||
// Bucket might be DNS compatible but dots in the hostname will fail
|
||||
// certificate validation, so do not use host-style.
|
||||
if r.HTTPRequest.URL.Scheme == "https" && strings.Contains(bucket, ".") {
|
||||
return false
|
||||
}
|
||||
|
||||
// Use host-style if the bucket is DNS compatible
|
||||
return dnsCompatibleBucketName(bucket)
|
||||
}
|
||||
|
||||
func updateHostWithBucket(r *aws.Request) {
|
||||
b := awsutil.ValuesAtPath(r.Params, "Bucket")
|
||||
if len(b) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if bucket := b[0].(string); bucket != "" && hostStyleBucketName(r, bucket) {
|
||||
r.HTTPRequest.URL.Host = bucket + "." + r.HTTPRequest.URL.Host
|
||||
r.HTTPRequest.URL.Path = strings.Replace(r.HTTPRequest.URL.Path, "/{Bucket}", "", -1)
|
||||
if r.HTTPRequest.URL.Path == "" {
|
||||
r.HTTPRequest.URL.Path = "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
306
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/inventory.go
generated
vendored
Normal file
306
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/inventory.go
generated
vendored
Normal file
@@ -0,0 +1,306 @@
|
||||
package s3
|
||||
|
||||
import "github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
|
||||
// PutBucketInventoryRequest generates a request for the PutBucketInventory operation.
|
||||
func (c *S3) PutBucketInventoryRequest(input *PutBucketInventoryInput) (req *aws.Request, output *PutBucketInventoryOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutBucketInventory",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?inventory",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutBucketInventoryInput{}
|
||||
}
|
||||
|
||||
input.AutoFillMD5 = true
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &PutBucketInventoryOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutBucketInventory creates a new inventory configuration.
|
||||
func (c *S3) PutBucketInventory(input *PutBucketInventoryInput) (*PutBucketInventoryOutput, error) {
|
||||
req, out := c.PutBucketInventoryRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketInventoryWithContext(ctx aws.Context, input *PutBucketInventoryInput) (*PutBucketInventoryOutput, error) {
|
||||
req, out := c.PutBucketInventoryRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type PutBucketInventoryInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
Id *string `location:"querystring" locationName:"id" type:"string" required:"true"`
|
||||
|
||||
InventoryConfiguration *InventoryConfiguration `locationName:"InventoryConfiguration" type:"structure" required:"true"`
|
||||
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutBucketInventoryInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutBucketInventoryInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"InventoryConfiguration"`
|
||||
|
||||
AutoFillMD5 bool
|
||||
}
|
||||
|
||||
type PutBucketInventoryOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
type InventoryConfiguration struct {
|
||||
// The list name specified by the user is unique within a single bucket.
|
||||
Id *string `locationName:"Id" type:"string" required:"true"`
|
||||
|
||||
// Is the inventory function enabled.
|
||||
IsEnabled *bool `locationName:"IsEnabled" type:"boolean" required:"true"`
|
||||
|
||||
// Specify scanning prefix information.
|
||||
Filter *InventoryFilter `locationName:"Filter" type:"structure"`
|
||||
|
||||
// Storage inventory results.
|
||||
Destination *Destination `locationName:"Destination" type:"structure" required:"true"`
|
||||
|
||||
// Container for storing inventory export cycle information.
|
||||
Schedule *Schedule `locationName:"Schedule" type:"structure" required:"true"`
|
||||
|
||||
// Set the configuration items included in the inventory results.
|
||||
OptionalFields *OptionalFields `locationName:"OptionalFields" type:"structure" required:"true"`
|
||||
}
|
||||
|
||||
type InventoryFilter struct {
|
||||
// The storage path prefix of the inventory file.
|
||||
Prefix *string `locationName:"Prefix" type:"string" required:"true"`
|
||||
|
||||
// The starting timestamp of the last modification time of the filtered file, in seconds.
|
||||
LastModifyBeginTimeStamp *string `locationName:"LastModifyBeginTimeStamp" type:"string"`
|
||||
|
||||
// End timestamp of the last modification time of the filtered file, in seconds.
|
||||
LastModifyEndTimeStamp *string `locationName:"LastModifyEndTimeStamp" type:"string"`
|
||||
}
|
||||
|
||||
type Destination struct {
|
||||
// Bucket information stored after exporting the inventory results.
|
||||
KS3BucketDestination *KS3BucketDestination `locationName:"KS3BucketDestination" type:"structure" required:"true"`
|
||||
}
|
||||
|
||||
type KS3BucketDestination struct {
|
||||
// The file format of the inventory file is a CSV file compressed using GZIP after exporting the manifest file.
|
||||
Format *string `locationName:"Format" type:"string" required:"true"`
|
||||
|
||||
// Bucket owner's account ID.
|
||||
AccountId *string `locationName:"AccountId" type:"string"`
|
||||
|
||||
// Bucket for storing exported inventory files.
|
||||
Bucket *string `locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// The storage path prefix of the inventory file.
|
||||
Prefix *string `locationName:"Prefix" type:"string"`
|
||||
}
|
||||
|
||||
type Schedule struct {
|
||||
// Cycle of exporting inventory files.
|
||||
Frequency *string `locationName:"Frequency" type:"string" required:"true"`
|
||||
}
|
||||
|
||||
type OptionalFields struct {
|
||||
// Configuration items included in the inventory results.
|
||||
// Valid values:
|
||||
// Size: The size of the object.
|
||||
// LastModifiedDate: The last modified time of an object.
|
||||
// ETag: The ETag value of an object, used to identify its contents.
|
||||
// StorageClass: The storage type of Object.
|
||||
// IsMultipartUploaded: Is it an object uploaded through shard upload method.
|
||||
// EncryptionStatus: Whether the object is encrypted. If the object is encrypted, the value of this field is True; otherwise, it is False.
|
||||
Field []*string `locationName:"Field" type:"list" flattened:"true"`
|
||||
}
|
||||
|
||||
// GetBucketInventoryRequest generates a request for the GetBucketInventory operation.
|
||||
func (c *S3) GetBucketInventoryRequest(input *GetBucketInventoryInput) (req *aws.Request, output *GetBucketInventoryOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetBucketInventory",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?inventory",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetBucketInventoryInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &GetBucketInventoryOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetBucketInventory gets the inventory configuration for the bucket.
|
||||
func (c *S3) GetBucketInventory(input *GetBucketInventoryInput) (*GetBucketInventoryOutput, error) {
|
||||
req, out := c.GetBucketInventoryRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketInventoryWithContext(ctx aws.Context, input *GetBucketInventoryInput) (*GetBucketInventoryOutput, error) {
|
||||
req, out := c.GetBucketInventoryRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetBucketInventoryInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
Id *string `location:"querystring" locationName:"id" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetBucketInventoryOutput struct {
|
||||
InventoryConfiguration *InventoryConfiguration `locationName:"Inventory" type:"structure"`
|
||||
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetBucketInventoryOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataGetBucketInventoryOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"InventoryConfiguration"`
|
||||
}
|
||||
|
||||
// DeleteBucketInventoryRequest generates a request for the DeleteBucketInventory operation.
|
||||
func (c *S3) DeleteBucketInventoryRequest(input *DeleteBucketInventoryInput) (req *aws.Request, output *DeleteBucketInventoryOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "DeleteBucketInventory",
|
||||
HTTPMethod: "DELETE",
|
||||
HTTPPath: "/{Bucket}?inventory",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DeleteBucketInventoryInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &DeleteBucketInventoryOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteBucketInventory deletes the inventory configuration for the bucket.
|
||||
func (c *S3) DeleteBucketInventory(input *DeleteBucketInventoryInput) (*DeleteBucketInventoryOutput, error) {
|
||||
req, out := c.DeleteBucketInventoryRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) DeleteBucketInventoryWithContext(ctx aws.Context, input *DeleteBucketInventoryInput) (*DeleteBucketInventoryOutput, error) {
|
||||
req, out := c.DeleteBucketInventoryRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type DeleteBucketInventoryInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
Id *string `location:"querystring" locationName:"id" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
type DeleteBucketInventoryOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// ListBucketInventoryRequest generates a request for the ListBucketInventory operation.
|
||||
func (c *S3) ListBucketInventoryRequest(input *ListBucketInventoryInput) (req *aws.Request, output *ListBucketInventoryOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "ListBucketInventory",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?inventory",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &ListBucketInventoryInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &ListBucketInventoryOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// ListBucketInventory lists the inventory configurations for the bucket.
|
||||
func (c *S3) ListBucketInventory(input *ListBucketInventoryInput) (*ListBucketInventoryOutput, error) {
|
||||
req, out := c.ListBucketInventoryRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) ListBucketInventoryWithContext(ctx aws.Context, input *ListBucketInventoryInput) (*ListBucketInventoryOutput, error) {
|
||||
req, out := c.ListBucketInventoryRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type ListBucketInventoryInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
ContinuationToken *string `location:"querystring" locationName:"continuation-token" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type ListInventoryConfigurationsResult struct {
|
||||
InventoryConfigurations []*InventoryConfiguration `locationName:"InventoryConfiguration" type:"list" flattened:"true"`
|
||||
|
||||
IsTruncated *bool `locationName:"IsTruncated" type:"boolean"`
|
||||
|
||||
NextContinuationToken *string `locationName:"NextContinuationToken" type:"string"`
|
||||
}
|
||||
|
||||
type ListBucketInventoryOutput struct {
|
||||
InventoryConfigurationsResult *ListInventoryConfigurationsResult `locationName:"InventoryConfigurationsResult" type:"structure"`
|
||||
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataListBucketInventoryOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataListBucketInventoryOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"InventoryConfigurationsResult"`
|
||||
}
|
||||
443
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/ks3bill.go
generated
vendored
Normal file
443
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/ks3bill.go
generated
vendored
Normal file
@@ -0,0 +1,443 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/signer/open_api"
|
||||
)
|
||||
|
||||
type QueryKs3DataInput struct {
|
||||
// 查询用量开始时间,格式为:yyyyMMdd,如:20250901 表示查询从2025年9月1日0点0分开始的用量
|
||||
StartTime *string `location:"querystring" locationName:"StartTime" type:"string" required:"true"`
|
||||
|
||||
// 查询用量结束时间,格式为:yyyyMMdd,如:20250902 表示查询到2025年9月2日23点59分结束的用量
|
||||
EndTime *string `location:"querystring" locationName:"EndTime" type:"string" required:"true"`
|
||||
|
||||
// 支持按天粒度查询,固定值:Day
|
||||
DateType *string `location:"querystring" locationName:"DateType" type:"string"`
|
||||
|
||||
// 存储空间名称,最多支持同时查询5个存储桶的用量明细
|
||||
BucketNames []string `location:"querystrings" locationName:"Bucketname" type:"list" required:"true"`
|
||||
|
||||
// 可以查询单个或多个计费项,如果不填,则查询除带宽外的所有计费项
|
||||
// DataSize:存储量
|
||||
// NetworkFlowUp:外网上行流量
|
||||
// NetworkFlow:外网下行流量
|
||||
// CDNFlow:CDN回源流量
|
||||
// ReplicationFlow:跨区域复制流量
|
||||
// RequestsGet:GET类请求次数
|
||||
// RequestsPut:PUT类请求次数
|
||||
// RestoreSize:数据取回量
|
||||
// TagNum:对象标签梳理
|
||||
// BandwidthUp:上行带宽(不区分外网和CDN)
|
||||
// BandwidthDown:下行带宽(不区分外网和CDN)
|
||||
// NetBandwidthUp:外网上行带宽
|
||||
// NetBandwidthDown:外网下行带宽
|
||||
// CDNBandwidthDown:CDN回源带宽
|
||||
// IntranetBandwidthUp:内网上行带宽
|
||||
// IntranetBandwidthDown:内网下行带宽
|
||||
// IntranetFlowUp:内网上行流量
|
||||
// IntranetFlowDown:内网下行流量
|
||||
// ObjectNum:桶内的对象数量
|
||||
Ks3Products []string `location:"querystrings" locationName:"Ks3Product" type:"list"`
|
||||
|
||||
// 可以查询单个或多个统计项的流量情况,可选值:Object、Referer、IP、UA,返回TOP200数据
|
||||
Transfers []string `location:"querystrings" locationName:"Transfer" type:"list"`
|
||||
|
||||
// 可以查询单个或多个统计项的请求次数情况,可选值:Object、Referer、IP、UA,返回TOP200数据
|
||||
Requests []string `location:"querystrings" locationName:"Request" type:"list"`
|
||||
}
|
||||
|
||||
type QueryKs3DataOutput struct {
|
||||
// 查询结果
|
||||
Ks3DataResult *Ks3DataResult `locationName:"Ks3DataResult" type:"structure"`
|
||||
|
||||
// 响应头
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// HTTP 状态码
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataQueryKs3DataOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataQueryKs3DataOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"Ks3DataResult"`
|
||||
}
|
||||
|
||||
type Ks3DataResult struct {
|
||||
// 响应码
|
||||
Code *string `locationName:"Code" type:"string"`
|
||||
|
||||
// 响应信息
|
||||
Message *string `locationName:"Message" type:"string"`
|
||||
|
||||
// 包含一个或多个Bucket的容器
|
||||
Data *Ks3Data `locationName:"Data" type:"structure"`
|
||||
|
||||
// 请求ID
|
||||
RequestId *string `locationName:"RequestId" type:"string"`
|
||||
}
|
||||
|
||||
type Ks3Data struct {
|
||||
// 包含一个或多个Bucket的列表
|
||||
Buckets []*Ks3DataBucket `locationName:"Buckets" type:"list"`
|
||||
}
|
||||
|
||||
type Ks3DataBucket struct {
|
||||
// Bucket的名称
|
||||
Name *string `locationName:"Name" type:"string"`
|
||||
|
||||
// 数据开始时间
|
||||
StartTime *string `locationName:"StartTime" type:"string"`
|
||||
|
||||
// 数据结束时间
|
||||
EndTime *string `locationName:"EndTime" type:"string"`
|
||||
|
||||
// Bucket的标准存储量,单位是Bytes
|
||||
StandardDataSize *string `locationName:"StandardDataSize" type:"string"`
|
||||
|
||||
// Bucket的低频存储量,单位是Bytes
|
||||
StandardIADataSize *string `locationName:"StandardIADataSize" type:"string"`
|
||||
|
||||
// Bucket的归档存储量,单位是Bytes
|
||||
ArchiveDataSize *string `locationName:"ArchiveDataSize" type:"string"`
|
||||
|
||||
// 标准存储的PUT请求次数
|
||||
StandardPutRequest *string `locationName:"StandardPutRequest" type:"string"`
|
||||
|
||||
// 低频存储的PUT请求次数
|
||||
StandardIAPutRequest *string `locationName:"StandardIAPutRequest" type:"string"`
|
||||
|
||||
// 归档存储的PUT请求次数
|
||||
ArchivePutRequest *string `locationName:"ArchivePutRequest" type:"string"`
|
||||
|
||||
// 标准存储的GET请求次数
|
||||
StandardGetRequest *string `locationName:"StandardGetRequest" type:"string"`
|
||||
|
||||
// 低频存储的GET请求次数
|
||||
StandardIAGetRequest *string `locationName:"StandardIAGetRequest" type:"string"`
|
||||
|
||||
// 归档存储的GET请求次数
|
||||
ArchiveGetRequest *string `locationName:"ArchiveGetRequest" type:"string"`
|
||||
|
||||
// 外网下行流量,单位是Bytes
|
||||
NetworkFlow *string `locationName:"NetworkFlow" type:"string"`
|
||||
|
||||
// CDN回源流量,单位是Bytes
|
||||
CDNFlow *string `locationName:"CDNFlow" type:"string"`
|
||||
|
||||
// 跨区域复制流量,单位是Bytes
|
||||
ReplicationFlow *string `locationName:"ReplicationFlow" type:"string"`
|
||||
|
||||
// 外网上行带宽,不区分外网上行和CDN上行,单位是bps
|
||||
BandwidthUp []map[string]*string `locationName:"BandwidthUp" type:"list"`
|
||||
|
||||
// 外网下行带宽,不区分外网下行和CDN下行,单位是bps
|
||||
BandwidthDown []map[string]*string `locationName:"BandwidthDown" type:"list"`
|
||||
|
||||
// 外网下行带宽,单位是bps
|
||||
OuterBandwidthDown []map[string]*string `locationName:"OuterBandwidthDown" type:"list"`
|
||||
|
||||
// CDN回源带宽,单位是bps
|
||||
CDNBandwidthDown []map[string]*string `locationName:"CDNBandwidthDown" type:"list"`
|
||||
|
||||
// 低频存储数据取回量,单位是Bytes
|
||||
StandardIAData *string `locationName:"StandardIAData" type:"string"`
|
||||
|
||||
// 外网上行带宽
|
||||
NetBandwidthUp []map[string]*string `locationName:"NetBandwidthUp" type:"list"`
|
||||
|
||||
// 外网上行流量
|
||||
NetworkFlowUp *string `locationName:"NetworkFlowUp" type:"string"`
|
||||
|
||||
// 内网上行带宽
|
||||
IntranetBandwidthUp []map[string]*string `locationName:"IntranetBandwidthUp" type:"list"`
|
||||
|
||||
// 内网上行流量
|
||||
IntranetFlowUp *string `locationName:"IntranetFlowUp" type:"string"`
|
||||
|
||||
// 内网下行带宽
|
||||
IntranetBandwidthDown []map[string]*string `locationName:"IntranetBandwidthDown" type:"list"`
|
||||
|
||||
// 内网下行流量
|
||||
IntranetFlowDown *string `locationName:"IntranetFlowDown" type:"string"`
|
||||
|
||||
// 桶内的对象数量
|
||||
ObjectNum *string `locationName:"ObjectNum" type:"string"`
|
||||
|
||||
// 归档存储解冻数据量,单位是Bytes
|
||||
ArchiveData *string `locationName:"ArchiveData" type:"string"`
|
||||
|
||||
// 对象标签的数量
|
||||
TagNum *string `locationName:"TagNum" type:"string"`
|
||||
|
||||
// Object、Referer、IP、UA产生的流量
|
||||
Transfer *Ks3DataTransfer `locationName:"Transfer" type:"structure"`
|
||||
|
||||
// Object、Referer、IP、UA产生的请求次数
|
||||
Request *Ks3DataRequest `locationName:"Request" type:"structure"`
|
||||
}
|
||||
|
||||
type Ks3DataTransfer struct {
|
||||
// 指定Object产生的流量
|
||||
Objects []*Ks3DataTransferObject `locationName:"Object" type:"list"`
|
||||
|
||||
// 指定Referer产生的流量
|
||||
Referers []*Ks3DataTransferReferer `locationName:"Referer" type:"list"`
|
||||
|
||||
// 指定IP产生的流量
|
||||
IPs []*Ks3DataTransferIP `locationName:"Ip" type:"list"`
|
||||
|
||||
// 指定UA产生的流量
|
||||
UAs []*Ks3DataTransferUA `locationName:"Ua" type:"list"`
|
||||
}
|
||||
|
||||
type Ks3DataTransferObject struct {
|
||||
// Object名称
|
||||
Object *string `locationName:"object" type:"string"`
|
||||
|
||||
// Object产生的流量
|
||||
Traffic *string `locationName:"traffic" type:"string"`
|
||||
}
|
||||
|
||||
type Ks3DataTransferReferer struct {
|
||||
// Referer名称
|
||||
Referer *string `locationName:"referer" type:"string"`
|
||||
|
||||
// Referer产生的流量
|
||||
Traffic *string `locationName:"traffic" type:"string"`
|
||||
}
|
||||
|
||||
type Ks3DataTransferIP struct {
|
||||
// IP地址
|
||||
IP *string `locationName:"ip" type:"string"`
|
||||
|
||||
// IP产生的流量
|
||||
Traffic *string `locationName:"traffic" type:"string"`
|
||||
}
|
||||
|
||||
type Ks3DataTransferUA struct {
|
||||
// UA名称
|
||||
UA *string `locationName:"ua" type:"string"`
|
||||
|
||||
// UA产生的流量
|
||||
Traffic *string `locationName:"traffic" type:"string"`
|
||||
}
|
||||
|
||||
type Ks3DataRequest struct {
|
||||
// 指定Object产生的流量
|
||||
Objects []*Ks3DataRequestObject `locationName:"Object" type:"list"`
|
||||
|
||||
// 指定Referer产生的流量
|
||||
Referers []*Ks3DataRequestReferer `locationName:"Referer" type:"list"`
|
||||
|
||||
// 指定IP产生的流量
|
||||
IPs []*Ks3DataRequestIP `locationName:"Ip" type:"list"`
|
||||
|
||||
// 指定UA产生的流量
|
||||
UAs []*Ks3DataRequestUA `locationName:"Ua" type:"list"`
|
||||
}
|
||||
|
||||
type Ks3DataRequestObject struct {
|
||||
// Object名称
|
||||
Object *string `locationName:"object" type:"string"`
|
||||
|
||||
// Object产生的请求次数
|
||||
Times *string `locationName:"times" type:"string"`
|
||||
}
|
||||
|
||||
type Ks3DataRequestReferer struct {
|
||||
// Referer名称
|
||||
Referer *string `locationName:"referer" type:"string"`
|
||||
|
||||
// Referer产生的请求次数
|
||||
Times *string `locationName:"times" type:"string"`
|
||||
}
|
||||
|
||||
type Ks3DataRequestIP struct {
|
||||
// IP地址
|
||||
IP *string `locationName:"ip" type:"string"`
|
||||
|
||||
// IP产生的请求次数
|
||||
Times *string `locationName:"times" type:"string"`
|
||||
}
|
||||
|
||||
type Ks3DataRequestUA struct {
|
||||
// UA名称
|
||||
UA *string `locationName:"ua" type:"string"`
|
||||
|
||||
// UA产生的请求次数
|
||||
Times *string `locationName:"times" type:"string"`
|
||||
}
|
||||
|
||||
// QueryKs3DataRequest generates a request for the QueryKs3DataRequest operation.
|
||||
func (c *S3) QueryKs3DataRequest(input *QueryKs3DataInput) (req *aws.Request, output *QueryKs3DataOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "QueryKs3Data",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/?Action=QueryKs3Data",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &QueryKs3DataInput{}
|
||||
}
|
||||
|
||||
if input.StartTime != nil && aws.ToString(input.StartTime) != "" {
|
||||
input.StartTime = aws.String(aws.ToString(input.StartTime) + "0000")
|
||||
}
|
||||
|
||||
if input.EndTime != nil && aws.ToString(input.EndTime) != "" {
|
||||
input.EndTime = aws.String(aws.ToString(input.EndTime) + "2359")
|
||||
}
|
||||
|
||||
if input.DateType == nil || aws.ToString(input.DateType) == "" {
|
||||
input.DateType = aws.String("Day")
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
req.RequestType = "ks3bill"
|
||||
req.ContentType = "application/json"
|
||||
req.HTTPRequest.URL.Host = c.Config.Ks3BillEndpoint
|
||||
req.Handlers.Sign.Clear()
|
||||
req.Handlers.Sign.PushBack(open_api.Sign)
|
||||
output = &QueryKs3DataOutput{
|
||||
Ks3DataResult: &Ks3DataResult{},
|
||||
}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// QueryKs3Data 桶用量详情及业务分析查询
|
||||
func (c *S3) QueryKs3Data(input *QueryKs3DataInput) (*QueryKs3DataOutput, error) {
|
||||
req, out := c.QueryKs3DataRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) QueryKs3DataWithContext(ctx aws.Context, input *QueryKs3DataInput) (*QueryKs3DataOutput, error) {
|
||||
req, out := c.QueryKs3DataRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type QueryBucketRankInput struct {
|
||||
// 查询用量开始时间,格式为:yyyyMMdd,如:20250901 表示查询从2025年9月1日0点0分开始的用量
|
||||
StartTime *string `location:"querystring" locationName:"StartTime" type:"string" required:"true"`
|
||||
|
||||
// 查询用量结束时间,格式为:yyyyMMdd,如:20250902 表示查询到2025年9月2日23点59分结束的用量
|
||||
EndTime *string `location:"querystring" locationName:"EndTime" type:"string" required:"true"`
|
||||
|
||||
// 支持按天粒度查询,固定值:Day
|
||||
DateType *string `location:"querystring" locationName:"DateType" type:"string"`
|
||||
|
||||
// 可以查询单个或多个统计项,如果不填,则查询所有统计项
|
||||
// DataSize:存储量
|
||||
// Flow:外网下行流量
|
||||
// RequestsGet:GET类请求次数
|
||||
// RequestsPut:PUT类请求次数
|
||||
Ks3Products []string `location:"querystrings" locationName:"Ks3Product" type:"list"`
|
||||
|
||||
// TOP排序的Bucket数量,取值范围为[1-500],默认值为200
|
||||
Number *int64 `location:"querystring" locationName:"Number" type:"integer"`
|
||||
}
|
||||
|
||||
type QueryBucketRankOutput struct {
|
||||
// 查询结果
|
||||
BucketRankResult *BucketRankResult `locationName:"BucketRankResult" type:"structure"`
|
||||
|
||||
// 响应头
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// HTTP 状态码
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataQueryBucketRankOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataQueryBucketRankOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"BucketRankResult"`
|
||||
}
|
||||
|
||||
type BucketRankResult struct {
|
||||
// 响应码
|
||||
Code *string `locationName:"Code" type:"string"`
|
||||
|
||||
// 响应信息
|
||||
Message *string `locationName:"Message" type:"string"`
|
||||
|
||||
// 桶用量排序数据
|
||||
Data *BucketRankData `locationName:"Data" type:"structure"`
|
||||
|
||||
// 请求ID
|
||||
RequestId *string `locationName:"RequestId" type:"string"`
|
||||
}
|
||||
|
||||
type BucketRankData struct {
|
||||
// Bucket的存储量,单位是Bytes
|
||||
DataSize []map[string]*string `locationName:"DataSize" type:"list"`
|
||||
|
||||
// Bucket的外网下行流量,单位是Bytes
|
||||
Flow []map[string]*string `locationName:"Flow" type:"list"`
|
||||
|
||||
// Bucket的GET类请求次数,单位是次
|
||||
RequestsGet []map[string]*string `locationName:"RequestsGet" type:"list"`
|
||||
|
||||
// Bucket的PUT类请求次数,单位是次
|
||||
RequestsPut []map[string]*string `locationName:"RequestsPut" type:"list"`
|
||||
}
|
||||
|
||||
// QueryBucketRankRequest generates a request for the QueryBucketRankRequest operation.
|
||||
func (c *S3) QueryBucketRankRequest(input *QueryBucketRankInput) (req *aws.Request, output *QueryBucketRankOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "QueryBucketRank",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/?Action=QueryBucketRank",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &QueryBucketRankInput{}
|
||||
}
|
||||
|
||||
if input.StartTime != nil && aws.ToString(input.StartTime) != "" {
|
||||
input.StartTime = aws.String(aws.ToString(input.StartTime) + "0000")
|
||||
}
|
||||
|
||||
if input.EndTime != nil && aws.ToString(input.EndTime) != "" {
|
||||
input.EndTime = aws.String(aws.ToString(input.EndTime) + "2359")
|
||||
}
|
||||
|
||||
if input.DateType == nil || aws.ToString(input.DateType) == "" {
|
||||
input.DateType = aws.String("Day")
|
||||
}
|
||||
|
||||
if input.Number == nil {
|
||||
input.Number = aws.Long(200)
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
req.RequestType = "ks3bill"
|
||||
req.ContentType = "application/json"
|
||||
req.HTTPRequest.URL.Host = c.Config.Ks3BillEndpoint
|
||||
req.Handlers.Sign.Clear()
|
||||
req.Handlers.Sign.PushBack(open_api.Sign)
|
||||
output = &QueryBucketRankOutput{
|
||||
BucketRankResult: &BucketRankResult{},
|
||||
}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// QueryBucketRank 桶用量排序查询
|
||||
func (c *S3) QueryBucketRank(input *QueryBucketRankInput) (*QueryBucketRankOutput, error) {
|
||||
req, out := c.QueryBucketRankRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) QueryBucketRankWithContext(ctx aws.Context, input *QueryBucketRankInput) (*QueryBucketRankOutput, error) {
|
||||
req, out := c.QueryBucketRankRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
261
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/lifecycle.go
generated
vendored
Normal file
261
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/lifecycle.go
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PutBucketLifecycleInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
LifecycleConfiguration *LifecycleConfiguration `locationName:"LifecycleConfiguration" type:"structure"`
|
||||
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// Specifies whether lifecycle rules allow prefix overlap.
|
||||
AllowSameActionOverlap *bool `location:"header" locationName:"x-amz-allow-same-action-overlap" type:"boolean"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutBucketLifecycleInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutBucketLifecycleInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"LifecycleConfiguration"`
|
||||
|
||||
AutoFillMD5 bool
|
||||
}
|
||||
|
||||
type LifecycleConfiguration struct {
|
||||
Rules []*LifecycleRule `locationName:"Rule" type:"list" flattened:"true" required:"true"`
|
||||
}
|
||||
|
||||
type LifecycleRule struct {
|
||||
// Unique identifier for the rule. The value cannot be longer than 255 characters.
|
||||
ID *string `type:"string"`
|
||||
|
||||
// If 'Enabled', the rule is currently being applied. If 'Disabled', the rule
|
||||
// is not currently being applied.
|
||||
Status *string `type:"string" required:"true"`
|
||||
|
||||
// Specifies the prefix, each Rule can only have one Filter, and the prefixes of different
|
||||
// Rules cannot conflict.
|
||||
Filter *LifecycleFilter `type:"structure"`
|
||||
|
||||
// Specifies the time when the object is deleted
|
||||
Expiration *LifecycleExpiration `type:"structure"`
|
||||
|
||||
// Specifies when an object transitions to a specified storage class.
|
||||
Transitions []*Transition `locationName:"Transition" type:"list" flattened:"true"`
|
||||
|
||||
// Specifies the expiration time for multipart uploads.
|
||||
AbortIncompleteMultipartUpload *AbortIncompleteMultipartUpload `type:"structure"`
|
||||
}
|
||||
|
||||
type LifecycleFilter struct {
|
||||
Prefix *string `type:"string"`
|
||||
And *And `locationName:"And" type:"structure"`
|
||||
}
|
||||
|
||||
type And struct {
|
||||
Prefix *string `type:"string"`
|
||||
Tags []*Tag `locationName:"Tag" type:"list" flattened:"true"`
|
||||
}
|
||||
|
||||
type LifecycleExpiration struct {
|
||||
// Indicates at what date the object is to be moved or deleted. Should be in
|
||||
// GMT ISO 8601 Format.
|
||||
Date *time.Time `type:"timestamp" timestampFormat:"iso8601"`
|
||||
|
||||
// Indicates the lifetime, in days, of the objects that are subject to the rule.
|
||||
// The value must be a non-zero positive integer.
|
||||
Days *int64 `type:"integer"`
|
||||
}
|
||||
|
||||
type Transition struct {
|
||||
// Indicates at what date the object is to be moved or deleted. Should be in
|
||||
// GMT ISO 8601 Format.
|
||||
Date *time.Time `type:"timestamp" timestampFormat:"iso8601"`
|
||||
|
||||
// Specifies the number of days after the object is last modified or accessed that the lifecycle rule takes effect.
|
||||
// When the value of IsAccessTime in the request is true, this parameter indicates that the lifecycle rule takes
|
||||
// effect based on the last access time of the object. When IsAccessTime is not set in the request or is set to false,
|
||||
// this parameter indicates that the lifecycle rule takes effect based on the last modification time of the object.
|
||||
// This parameter is mutually exclusive with Date.
|
||||
Days *int64 `type:"integer"`
|
||||
|
||||
// The class of storage used to store the object.
|
||||
StorageClass *string `type:"string"`
|
||||
|
||||
// Specifies whether to use the last access time matching rule.
|
||||
// true: indicates that the last access time of the object is used for matching.
|
||||
// false: indicates that the last modification time of the object is used for matching.
|
||||
IsAccessTime *bool `type:"boolean"`
|
||||
|
||||
// Specifies whether to convert the object to the source storage type when accessed again after the object is
|
||||
// converted to another storage type. This is only valid when IsAccessTime is set to true.
|
||||
// true: Indicates that the object is converted to the source storage type when accessed again.
|
||||
// false: Indicates that the object is still the target storage type when accessed again.
|
||||
ReturnToStdWhenVisit *bool `type:"boolean"`
|
||||
}
|
||||
|
||||
type AbortIncompleteMultipartUpload struct {
|
||||
// Relative expiration time: The expiration time in days after the last modified time
|
||||
DaysAfterInitiation *int64 `type:"integer"`
|
||||
// objects created before the date will be expired
|
||||
Date *string `type:"string"`
|
||||
}
|
||||
|
||||
type PutBucketLifecycleOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// PutBucketLifecycleRequest generates a request for the PutBucketLifecycle operation.
|
||||
func (c *S3) PutBucketLifecycleRequest(input *PutBucketLifecycleInput) (req *aws.Request, output *PutBucketLifecycleOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutBucketLifecycle",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?lifecycle",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutBucketLifecycleInput{}
|
||||
}
|
||||
|
||||
input.AutoFillMD5 = true
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &PutBucketLifecycleOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutBucketLifecycle Sets lifecycle configuration for your bucket. If a lifecycle configuration
|
||||
// exists, it replaces it.
|
||||
func (c *S3) PutBucketLifecycle(input *PutBucketLifecycleInput) (*PutBucketLifecycleOutput, error) {
|
||||
req, out := c.PutBucketLifecycleRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketLifecycleWithContext(ctx aws.Context, input *PutBucketLifecycleInput) (*PutBucketLifecycleOutput, error) {
|
||||
req, out := c.PutBucketLifecycleRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetBucketLifecycleInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetBucketLifecycleOutput struct {
|
||||
Rules []*LifecycleRule `locationName:"Rule" type:"list" flattened:"true"`
|
||||
|
||||
metadataGetBucketLifecycleOutput `json:"-" xml:"-"`
|
||||
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
type metadataGetBucketLifecycleOutput struct {
|
||||
SDKShapeTraits bool `type:"structure"`
|
||||
}
|
||||
|
||||
// GetBucketLifecycleRequest generates a request for the GetBucketLifecycle operation.
|
||||
func (c *S3) GetBucketLifecycleRequest(input *GetBucketLifecycleInput) (req *aws.Request, output *GetBucketLifecycleOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetBucketLifecycle",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?lifecycle",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetBucketLifecycleInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &GetBucketLifecycleOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetBucketLifecycle Returns the lifecycle configuration information set on the bucket.
|
||||
func (c *S3) GetBucketLifecycle(input *GetBucketLifecycleInput) (*GetBucketLifecycleOutput, error) {
|
||||
req, out := c.GetBucketLifecycleRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketLifecycleWithContext(ctx aws.Context, input *GetBucketLifecycleInput) (*GetBucketLifecycleOutput, error) {
|
||||
req, out := c.GetBucketLifecycleRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type DeleteBucketLifecycleInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type DeleteBucketLifecycleOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// DeleteBucketLifecycleRequest generates a request for the DeleteBucketLifecycle operation.
|
||||
func (c *S3) DeleteBucketLifecycleRequest(input *DeleteBucketLifecycleInput) (req *aws.Request, output *DeleteBucketLifecycleOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "DeleteBucketLifecycle",
|
||||
HTTPMethod: "DELETE",
|
||||
HTTPPath: "/{Bucket}?lifecycle",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DeleteBucketLifecycleInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &DeleteBucketLifecycleOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteBucketLifecycle Deletes the lifecycle configuration from the bucket.
|
||||
func (c *S3) DeleteBucketLifecycle(input *DeleteBucketLifecycleInput) (*DeleteBucketLifecycleOutput, error) {
|
||||
req, out := c.DeleteBucketLifecycleRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) DeleteBucketLifecycleWithContext(ctx aws.Context, input *DeleteBucketLifecycleInput) (*DeleteBucketLifecycleOutput, error) {
|
||||
req, out := c.DeleteBucketLifecycleRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
214
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/mirror.go
generated
vendored
Normal file
214
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/mirror.go
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
type BucketMirror struct {
|
||||
Version *string `json:"version" type:"string" locationName:"version"`
|
||||
UseDefaultRobots *bool `json:"use_default_robots" locationName:"use_default_robots"`
|
||||
AsyncMirrorRule *AsyncMirrorRule `json:"async_mirror_rule,omitempty" type:"structure" locationName:"async_mirror_rule"`
|
||||
SyncMirrorRules []*SyncMirrorRules `json:"sync_mirror_rules,omitempty" type:"list" locationName:"sync_mirror_rules"`
|
||||
CreatedTime *string `json:"created_time,omitempty" type:"string" locationName:"created_time"`
|
||||
LastModifiedTime *string `json:"last_modified_time,omitempty" type:"string" locationName:"last_modified_time"`
|
||||
}
|
||||
type SavingSetting struct {
|
||||
ACL *string `json:"acl,omitempty" required:"true" locationName:"acl"`
|
||||
}
|
||||
type AsyncMirrorRule struct {
|
||||
MirrorUrls []*string `json:"mirror_urls,omitempty" required:"true" locationName:"mirror_urls"`
|
||||
SavingSetting *SavingSetting `json:"saving_setting,omitempty" required:"true" locationName:"saving_setting"`
|
||||
MirrorType *string `json:"mirror_type,omitempty" locationName:"mirror_type"`
|
||||
}
|
||||
type MatchCondition struct {
|
||||
HTTPCodes []*string `json:"http_codes" locationName:"http_codes"`
|
||||
KeyPrefixes []*string `json:"key_prefixes" locationName:"key_prefixes"`
|
||||
}
|
||||
type SetHeaders struct {
|
||||
Key *string `json:"key,omitempty" locationName:"key"`
|
||||
Value *string `json:"value,omitempty" locationName:"value"`
|
||||
}
|
||||
type RemoveHeaders struct {
|
||||
Key *string `json:"key,omitempty" locationName:"key"`
|
||||
}
|
||||
type PassHeaders struct {
|
||||
Key *string `json:"key,omitempty" locationName:"key"`
|
||||
}
|
||||
type HeaderSetting struct {
|
||||
SetHeaders []*SetHeaders `json:"set_headers,omitempty" locationName:"set_headers"`
|
||||
RemoveHeaders []*RemoveHeaders `json:"remove_headers,omitempty" locationName:"remove_headers"`
|
||||
PassAll *bool `json:"pass_all,omitempty" locationName:"pass_all"`
|
||||
PassHeaders []*PassHeaders `json:"pass_headers,omitempty" locationName:"pass_headers"`
|
||||
}
|
||||
type MirrorRequestSetting struct {
|
||||
PassQueryString *bool `json:"pass_query_string,omitempty" locationName:"pass_query_string"`
|
||||
Follow3Xx *bool `json:"follow3xx,omitempty" locationName:"follow3xx"`
|
||||
HeaderSetting *HeaderSetting `json:"header_setting,omitempty" locationName:"header_setting"`
|
||||
}
|
||||
type SyncMirrorRules struct {
|
||||
MatchCondition MatchCondition `json:"match_condition" locationName:"match_condition"`
|
||||
MirrorURL *string `json:"mirror_url,omitempty" locationName:"mirror_url"`
|
||||
MirrorRequestSetting *MirrorRequestSetting `json:"mirror_request_setting,omitempty" locationName:"mirror_request_setting"`
|
||||
SavingSetting *SavingSetting `json:"saving_setting,omitempty" locationName:"saving_setting"`
|
||||
MirrorType *string `json:"mirror_type,omitempty" locationName:"mirror_type"`
|
||||
}
|
||||
|
||||
type PutBucketMirrorInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
BucketMirror *BucketMirror `locationName:"BucketMirror" json:"-" type:"structure"`
|
||||
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutBucketMirrorInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutBucketMirrorInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"BucketMirror"`
|
||||
}
|
||||
|
||||
type PutBucketMirrorOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
type GetBucketMirrorInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
type GetBucketMirrorOutput struct {
|
||||
BucketMirror *BucketMirror `locationName:"BucketMirror" type:"structure"`
|
||||
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetBucketMirrorInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataGetBucketMirrorInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"BucketMirror"`
|
||||
}
|
||||
|
||||
type DeleteBucketMirrorInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
type DeleteBucketMirrorOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketMirrorRequest(input *PutBucketMirrorInput) (req *aws.Request, output *PutBucketMirrorOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutBucketMirror",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?mirror",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutBucketMirrorInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
req.ContentType = "application/json"
|
||||
output = &PutBucketMirrorOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketMirror(input *PutBucketMirrorInput) (*PutBucketMirrorOutput, error) {
|
||||
req, out := c.PutBucketMirrorRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketMirrorWithContext(ctx aws.Context, input *PutBucketMirrorInput) (*PutBucketMirrorOutput, error) {
|
||||
req, out := c.PutBucketMirrorRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketMirrorRequest(input *GetBucketMirrorInput) (req *aws.Request, output *GetBucketMirrorOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetBucketMirror",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?mirror",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetBucketMirrorInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
req.ContentType = "application/json"
|
||||
output = &GetBucketMirrorOutput{
|
||||
BucketMirror: &BucketMirror{},
|
||||
}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketMirror(input *GetBucketMirrorInput) (*GetBucketMirrorOutput, error) {
|
||||
req, out := c.GetBucketMirrorRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketMirrorWithContext(ctx aws.Context, input *GetBucketMirrorInput) (*GetBucketMirrorOutput, error) {
|
||||
req, out := c.GetBucketMirrorRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) DeleteBucketMirrorRequest(input *DeleteBucketMirrorInput) (req *aws.Request, output *DeleteBucketMirrorOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "DeleteBucketMirror",
|
||||
HTTPMethod: "DELETE",
|
||||
HTTPPath: "/{Bucket}?mirror",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DeleteBucketMirrorInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &DeleteBucketMirrorOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
func (c *S3) DeleteBucketMirror(input *DeleteBucketMirrorInput) (*DeleteBucketMirrorOutput, error) {
|
||||
req, out := c.DeleteBucketMirrorRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) DeleteBucketMirrorWithContext(ctx aws.Context, input *DeleteBucketMirrorInput) (*DeleteBucketMirrorOutput, error) {
|
||||
req, out := c.DeleteBucketMirrorRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
190
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/replication.go
generated
vendored
Normal file
190
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/replication.go
generated
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
package s3
|
||||
|
||||
import "github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
|
||||
// PutBucketReplicationRequest generates a request for the PutBucketReplication operation.
|
||||
func (c *S3) PutBucketReplicationRequest(input *PutBucketReplicationInput) (req *aws.Request, output *PutBucketReplicationOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutBucketReplication",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?crr",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutBucketReplicationInput{}
|
||||
}
|
||||
|
||||
input.AutoFillMD5 = true
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &PutBucketReplicationOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutBucketReplication creates a new replication configuration.
|
||||
func (c *S3) PutBucketReplication(input *PutBucketReplicationInput) (*PutBucketReplicationOutput, error) {
|
||||
req, out := c.PutBucketReplicationRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketReplicationWithContext(ctx aws.Context, input *PutBucketReplicationInput) (*PutBucketReplicationOutput, error) {
|
||||
req, out := c.PutBucketReplicationRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type PutBucketReplicationInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
ReplicationConfiguration *ReplicationConfiguration `locationName:"Replication" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
|
||||
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutBucketReplicationInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutBucketReplicationInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"ReplicationConfiguration"`
|
||||
|
||||
AutoFillMD5 bool
|
||||
}
|
||||
|
||||
type PutBucketReplicationOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
type ReplicationConfiguration struct {
|
||||
// Prefix matching, only objects that match prefix rules will be copied. Each copying rule
|
||||
// can add up to 10 prefix matching rules, and prefixes cannot overlap with each other.
|
||||
Prefix []*string `locationName:"prefix" type:"list" flattened:"true"`
|
||||
|
||||
// Indicate whether to enable delete replication. If set to Enabled, it means enabled; if set to
|
||||
// Disabled or not, it means disabled. If set to delete replication, when the source bucket deletes
|
||||
// an object, the replica of that object in the target bucket will also be deleted.
|
||||
DeleteMarkerStatus *string `locationName:"DeleteMarkerStatus" type:"string" required:"true"`
|
||||
|
||||
// Target bucket for copying rules.
|
||||
TargetBucket *string `locationName:"targetBucket" type:"string" required:"true"`
|
||||
|
||||
// Specify whether to copy historical data. Whether to copy the data from the source bucket
|
||||
// to the target bucket before enabling data replication.
|
||||
// Enabled: Copy historical data to the target bucket (default value)
|
||||
// Disabled: Do not copy historical data, only copy new data after enabling the rule to the target bucket.
|
||||
HistoricalObjectReplication *string `locationName:"HistoricalObjectReplication" type:"string"`
|
||||
|
||||
// Region of the target bucket.
|
||||
Region *string `locationName:"region" type:"string"`
|
||||
}
|
||||
|
||||
// GetBucketReplicationRequest generates a request for the GetBucketReplication operation.
|
||||
func (c *S3) GetBucketReplicationRequest(input *GetBucketReplicationInput) (req *aws.Request, output *GetBucketReplicationOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetBucketReplication",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?crr",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetBucketReplicationInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &GetBucketReplicationOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetBucketReplication gets the replication configuration for the bucket.
|
||||
func (c *S3) GetBucketReplication(input *GetBucketReplicationInput) (*GetBucketReplicationOutput, error) {
|
||||
req, out := c.GetBucketReplicationRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketReplicationWithContext(ctx aws.Context, input *GetBucketReplicationInput) (*GetBucketReplicationOutput, error) {
|
||||
req, out := c.GetBucketReplicationRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetBucketReplicationInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetBucketReplicationOutput struct {
|
||||
ReplicationConfiguration *ReplicationConfiguration `locationName:"Replication" type:"structure"`
|
||||
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetBucketReplicationOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataGetBucketReplicationOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"ReplicationConfiguration"`
|
||||
}
|
||||
|
||||
// DeleteBucketReplicationRequest generates a request for the DeleteBucketReplication operation.
|
||||
func (c *S3) DeleteBucketReplicationRequest(input *DeleteBucketReplicationInput) (req *aws.Request, output *DeleteBucketReplicationOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "DeleteBucketReplication",
|
||||
HTTPMethod: "DELETE",
|
||||
HTTPPath: "/{Bucket}?crr",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DeleteBucketReplicationInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &DeleteBucketReplicationOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteBucketReplication deletes the replication configuration for the bucket.
|
||||
func (c *S3) DeleteBucketReplication(input *DeleteBucketReplicationInput) (*DeleteBucketReplicationOutput, error) {
|
||||
req, out := c.DeleteBucketReplicationRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) DeleteBucketReplicationWithContext(ctx aws.Context, input *DeleteBucketReplicationInput) (*DeleteBucketReplicationOutput, error) {
|
||||
req, out := c.DeleteBucketReplicationRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type DeleteBucketReplicationInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
type DeleteBucketReplicationOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
194
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/requester_qos.go
generated
vendored
Normal file
194
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/requester_qos.go
generated
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
type PutRequesterQosInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Requester flow control configuration container.
|
||||
RequesterQosConfiguration *RequesterQosConfiguration `locationName:"RequesterQosConfiguration" type:"structure" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutRequesterQosInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutRequesterQosInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"RequesterQosConfiguration"`
|
||||
}
|
||||
|
||||
type RequesterQosConfiguration struct {
|
||||
// Set the requester flow control rules.
|
||||
Rules []*RequesterQosRule `locationName:"Rule" type:"list" flattened:"true" required:"true"`
|
||||
}
|
||||
|
||||
type RequesterQosRule struct {
|
||||
// Specify the account type that needs flow control.
|
||||
// Optional values: User/Role.
|
||||
UserType *string `locationName:"UserType" type:"string" required:"true"`
|
||||
|
||||
// Specify the account that needs flow control.
|
||||
// Format: accountId/userName、accountId/roleName.
|
||||
Krn *string `locationName:"Krn" type:"string" required:"true"`
|
||||
|
||||
// Set access account flow control quota.
|
||||
Quotas []*BucketQosQuota `locationName:"Quota" type:"list" flattened:"true" required:"true"`
|
||||
}
|
||||
|
||||
type PutRequesterQosOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// PutRequesterQosRequest generates a request for the PutRequesterQos operation.
|
||||
func (c *S3) PutRequesterQosRequest(input *PutRequesterQosInput) (req *aws.Request, output *PutRequesterQosOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutRequesterQos",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?requesterqos",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutRequesterQosInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &PutRequesterQosOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutRequesterQos sets requester flow control configuration.
|
||||
func (c *S3) PutRequesterQos(input *PutRequesterQosInput) (*PutRequesterQosOutput, error) {
|
||||
req, out := c.PutRequesterQosRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutRequesterQosWithContext(ctx aws.Context, input *PutRequesterQosInput) (*PutRequesterQosOutput, error) {
|
||||
req, out := c.PutRequesterQosRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetRequesterQosInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetRequesterQosOutput struct {
|
||||
// Requester flow control configuration container.
|
||||
RequesterQosConfiguration *RequesterQosConfiguration `locationName:"RequesterQosConfiguration" type:"structure"`
|
||||
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetRequesterQosOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataGetRequesterQosOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"RequesterQosConfiguration"`
|
||||
}
|
||||
|
||||
// GetRequesterQosRequest generates a request for the GetRequesterQos operation.
|
||||
func (c *S3) GetRequesterQosRequest(input *GetRequesterQosInput) (req *aws.Request, output *GetRequesterQosOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetRequesterQos",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?requesterqos",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetRequesterQosInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &GetRequesterQosOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetRequesterQos gets requester flow control configuration.
|
||||
func (c *S3) GetRequesterQos(input *GetRequesterQosInput) (*GetRequesterQosOutput, error) {
|
||||
req, out := c.GetRequesterQosRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetRequesterQosWithContext(ctx aws.Context, input *GetRequesterQosInput) (*GetRequesterQosOutput, error) {
|
||||
req, out := c.GetRequesterQosRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type DeleteRequesterQosInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type DeleteRequesterQosOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// DeleteRequesterQosRequest generates a request for the DeleteRequesterQos operation.
|
||||
func (c *S3) DeleteRequesterQosRequest(input *DeleteRequesterQosInput) (req *aws.Request, output *DeleteRequesterQosOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "DeleteRequesterQos",
|
||||
HTTPMethod: "DELETE",
|
||||
HTTPPath: "/{Bucket}?requesterqos",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DeleteRequesterQosInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &DeleteRequesterQosOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteRequesterQos deletes requester flow control configuration.
|
||||
func (c *S3) DeleteRequesterQos(input *DeleteRequesterQosInput) (*DeleteRequesterQosOutput, error) {
|
||||
req, out := c.DeleteRequesterQosRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) DeleteRequesterQosWithContext(ctx aws.Context, input *DeleteRequesterQosInput) (*DeleteRequesterQosOutput, error) {
|
||||
req, out := c.DeleteRequesterQosRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
386
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/retention.go
generated
vendored
Normal file
386
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/retention.go
generated
vendored
Normal file
@@ -0,0 +1,386 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PutBucketRetentionRequest generates a request for the PutBucketRetention operation.
|
||||
func (c *S3) PutBucketRetentionRequest(input *PutBucketRetentionInput) (req *aws.Request, output *PutBucketRetentionOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutBucketRetention",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/{Bucket}?retention",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutBucketRetentionInput{}
|
||||
}
|
||||
|
||||
input.AutoFillMD5 = true
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &PutBucketRetentionOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutBucketRetention sets the retention configuration on a bucket.
|
||||
func (c *S3) PutBucketRetention(input *PutBucketRetentionInput) (*PutBucketRetentionOutput, error) {
|
||||
req, out := c.PutBucketRetentionRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutBucketRetentionWithContext(ctx aws.Context, input *PutBucketRetentionInput) (*PutBucketRetentionOutput, error) {
|
||||
req, out := c.PutBucketRetentionRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type PutBucketRetentionInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
RetentionConfiguration *BucketRetentionConfiguration `locationName:"RetentionConfiguration" type:"structure"`
|
||||
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutBucketRetentionInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutBucketRetentionInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"RetentionConfiguration"`
|
||||
|
||||
AutoFillMD5 bool
|
||||
}
|
||||
|
||||
type BucketRetentionConfiguration struct {
|
||||
// Whether to enable multiple versions in the recycle bin. When the request does not carry this parameter,
|
||||
// multiple versions are enabled by default.
|
||||
EnableMultipleVersion *bool `locationName:"EnableMultipleVersion" type:"boolean"`
|
||||
|
||||
// A container that contains a specific rule for the recycle bin.
|
||||
Rule *RetentionRule `locationName:"Rule" type:"structure" required:"true"`
|
||||
}
|
||||
|
||||
type RetentionRule struct {
|
||||
// The open status of the recycle bin is not case-sensitive.
|
||||
// Valid values: Enabled, Disabled. Enabled indicates enabling the recycle bin, Disabled indicates disabling the recycle bin.
|
||||
Status *string `locationName:"Status" type:"string" required:"true"`
|
||||
|
||||
// Specify how many days after the object enters the recycle bin to be completely deleted.
|
||||
// When Days is not set, the object will be permanently retained in the recycle bin after deletion.
|
||||
// Value range: 1-365
|
||||
Days *int64 `locationName:"Days" type:"integer"`
|
||||
}
|
||||
|
||||
type PutBucketRetentionOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// GetBucketRetentionRequest generates a request for the GetBucketRetention operation.
|
||||
func (c *S3) GetBucketRetentionRequest(input *GetBucketRetentionInput) (req *aws.Request, output *GetBucketRetentionOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetBucketRetention",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?retention",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetBucketRetentionInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &GetBucketRetentionOutput{
|
||||
RetentionConfiguration: &BucketRetentionConfiguration{},
|
||||
}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetBucketRetention gets the retention configuration for the bucket.
|
||||
func (c *S3) GetBucketRetention(input *GetBucketRetentionInput) (*GetBucketRetentionOutput, error) {
|
||||
req, out := c.GetBucketRetentionRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetBucketRetentionWithContext(ctx aws.Context, input *GetBucketRetentionInput) (*GetBucketRetentionOutput, error) {
|
||||
req, out := c.GetBucketRetentionRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetBucketRetentionInput struct {
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetBucketRetentionOutput struct {
|
||||
RetentionConfiguration *BucketRetentionConfiguration `locationName:"RetentionConfiguration" type:"structure"`
|
||||
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetBucketRetentionInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataGetBucketRetentionInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"RetentionConfiguration"`
|
||||
}
|
||||
|
||||
// ListRetentionRequest generates a request for the ListRetention operation.
|
||||
func (c *S3) ListRetentionRequest(input *ListRetentionInput) (req *aws.Request, output *ListRetentionOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "ListRetention",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/{Bucket}?recycle",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &ListRetentionInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &ListRetentionOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// ListRetention lists the objects in the recycle bin.
|
||||
func (c *S3) ListRetention(input *ListRetentionInput) (*ListRetentionOutput, error) {
|
||||
req, out := c.ListRetentionRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) ListRetentionWithContext(ctx aws.Context, input *ListRetentionInput) (*ListRetentionOutput, error) {
|
||||
req, out := c.ListRetentionRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type ListRetentionInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Specifies the key to start with when listing objects in a bucket.
|
||||
Marker *string `location:"querystring" locationName:"marker" type:"string"`
|
||||
|
||||
// Sets the maximum number of keys returned in the response. The response might
|
||||
// contain fewer keys but will never contain more.
|
||||
MaxKeys *int64 `location:"querystring" locationName:"max-keys" type:"integer"`
|
||||
|
||||
// Limits the response to keys that begin with the specified prefix.
|
||||
Prefix *string `location:"querystring" locationName:"prefix" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type ListRetentionOutput struct {
|
||||
// A container that lists information about the list of objects in the recycle bin.
|
||||
ListRetentionResult *ListRetentionResult `locationName:"ListRetentionResult" type:"structure"`
|
||||
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataListRetentionOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataListRetentionOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"ListRetentionResult"`
|
||||
}
|
||||
|
||||
type ListRetentionResult struct {
|
||||
// The name of the bucket.
|
||||
Name *string `type:"string"`
|
||||
|
||||
// Specify the prefix of the Key when requesting this List.
|
||||
Prefix *string `type:"string"`
|
||||
|
||||
// The maximum number of objects returned is 1000 by default.
|
||||
MaxKeys *int64 `type:"integer"`
|
||||
|
||||
// Specify the starting position of the object in the target bucket.
|
||||
Marker *string `type:"string"`
|
||||
|
||||
// The starting point for the next listed file. Users can use this value as a marker parameter
|
||||
// for the next List Retention.
|
||||
NextMarker *string `type:"string"`
|
||||
|
||||
// Whether it has been truncated. If the number of records in the Object list exceeds the set
|
||||
// maximum value, it will be truncated.
|
||||
IsTruncated *bool `type:"boolean"`
|
||||
|
||||
// The encoding method for Object names.
|
||||
EncodingType *string `type:"string"`
|
||||
|
||||
// List of Objects Listed.
|
||||
Contents []*RetentionObject `type:"list" flattened:"true"`
|
||||
}
|
||||
|
||||
type RetentionObject struct {
|
||||
// The key of the object.
|
||||
Key *string `type:"string"`
|
||||
|
||||
// The size of the object is measured in bytes.
|
||||
Size *int64 `type:"integer"`
|
||||
|
||||
// The entity label of an object, ETag, is generated when uploading an object to identify its content.
|
||||
ETag *string `type:"string"`
|
||||
|
||||
// The last time the object was modified.
|
||||
LastModified *time.Time `type:"timestamp" timestampFormat:"iso8601"`
|
||||
|
||||
// The owner information of this bucket.
|
||||
Owner *Owner `type:"structure"`
|
||||
|
||||
// The class of storage used to store the object.
|
||||
StorageClass *string `type:"string"`
|
||||
|
||||
// The version ID of the object.
|
||||
RetentionId *string `type:"string"`
|
||||
|
||||
// The time when the object was moved to the recycle bin.
|
||||
RecycleTime *time.Time `type:"timestamp" timestampFormat:"iso8601"`
|
||||
|
||||
// The time when an object is completely deleted from the recycle bin.
|
||||
EstimatedClearTime *time.Time `type:"timestamp" timestampFormat:"iso8601"`
|
||||
}
|
||||
|
||||
// RecoverObjectRequest generates a request for the RecoverObject operation.
|
||||
func (c *S3) RecoverObjectRequest(input *RecoverObjectInput) (req *aws.Request, output *RecoverObjectOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "RecoverObject",
|
||||
HTTPMethod: "POST",
|
||||
HTTPPath: "/{Bucket}/{Key+}?recover",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &RecoverObjectInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &RecoverObjectOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// RecoverObject recovers the object from the recycle bin.
|
||||
func (c *S3) RecoverObject(input *RecoverObjectInput) (*RecoverObjectOutput, error) {
|
||||
req, out := c.RecoverObjectRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) RecoverObjectWithContext(ctx aws.Context, input *RecoverObjectInput) (*RecoverObjectOutput, error) {
|
||||
req, out := c.RecoverObjectRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type RecoverObjectInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// The key of the object.
|
||||
Key *string `location:"uri" locationName:"Key" type:"string" required:"true"`
|
||||
|
||||
// Does it support overwriting when an object with the same name exists in the bucket after being
|
||||
// recovered from the recycle bin. When the value is true, it indicates overwriting, and the overwritten
|
||||
// objects in the bucket will enter the recycle bin.
|
||||
RetentionOverwrite *bool `location:"header" locationName:"x-kss-retention-overwrite" type:"boolean"`
|
||||
|
||||
// Specify the deletion ID of the recovered object. When the request header is not included,
|
||||
// only the latest version is restored by default.
|
||||
RetentionId *string `location:"header" locationName:"x-kss-retention-id" type:"string"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type RecoverObjectOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// ClearObjectRequest generates a request for the ClearObject operation.
|
||||
func (c *S3) ClearObjectRequest(input *ClearObjectInput) (req *aws.Request, output *ClearObjectOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "ClearObject",
|
||||
HTTPMethod: "DELETE",
|
||||
HTTPPath: "/{Bucket}/{Key+}?clear",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &ClearObjectInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &ClearObjectOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// ClearObject clears the object from the recycle bin.
|
||||
func (c *S3) ClearObject(input *ClearObjectInput) (*ClearObjectOutput, error) {
|
||||
req, out := c.ClearObjectRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) ClearObjectWithContext(ctx aws.Context, input *ClearObjectInput) (*ClearObjectOutput, error) {
|
||||
req, out := c.ClearObjectRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type ClearObjectInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// The key of the object.
|
||||
Key *string `location:"uri" locationName:"Key" type:"string" required:"true"`
|
||||
|
||||
// Specify the deletion ID of the deleted object.
|
||||
RetentionId *string `location:"header" locationName:"x-kss-retention-id" type:"string" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type ClearObjectOutput struct {
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
70
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/service.go
generated
vendored
Normal file
70
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/service.go
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/protocol/body"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/signer/v2"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/signer/v4"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// S3 is a client for Amazon S3.
|
||||
type S3 struct {
|
||||
*aws.Service
|
||||
}
|
||||
|
||||
// Used for custom service initialization logic
|
||||
var initService func(*aws.Service)
|
||||
|
||||
// Used for custom request initialization logic
|
||||
var initRequest func(*aws.Request)
|
||||
|
||||
// New returns a new S3 client.
|
||||
func New(config *aws.Config) *S3 {
|
||||
service := &aws.Service{
|
||||
Config: aws.DefaultConfig.Merge(config),
|
||||
ServiceName: "s3",
|
||||
APIVersion: "2006-03-01",
|
||||
}
|
||||
service.Initialize()
|
||||
|
||||
// Handlers
|
||||
if service.Config.SignerVersion == "V4" || service.Config.SignerVersion == "V4_UNSIGNED_PAYLOAD_SIGNER" {
|
||||
service.Handlers.Sign.PushBack(v4.Sign)
|
||||
} else {
|
||||
service.Handlers.Sign.PushBack(v2.Sign)
|
||||
}
|
||||
|
||||
service.Handlers.Build.PushBack(body.Build)
|
||||
service.Handlers.Unmarshal.PushBack(body.UnmarshalBody)
|
||||
service.Handlers.UnmarshalMeta.PushBack(body.UnmarshalMeta)
|
||||
service.Handlers.UnmarshalError.PushBack(body.UnmarshalError)
|
||||
|
||||
// Run custom service initialization if present
|
||||
if initService != nil {
|
||||
initService(service)
|
||||
}
|
||||
|
||||
return &S3{service}
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a S3 operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *S3) newRequest(op *aws.Operation, params, data interface{}) *aws.Request {
|
||||
r := aws.NewRequest(c.Service, op, params, data)
|
||||
if r.Config.DomainMode {
|
||||
r.HTTPRequest.URL.Path = strings.Replace(r.HTTPRequest.URL.Path, "/{Bucket}", "", -1)
|
||||
if r.HTTPRequest.URL.Path == "" {
|
||||
r.HTTPRequest.URL.Path = "/"
|
||||
}
|
||||
} else {
|
||||
updateHostWithBucket(r)
|
||||
}
|
||||
// Run custom request initialization if present
|
||||
if initRequest != nil {
|
||||
initRequest(r)
|
||||
}
|
||||
return r
|
||||
}
|
||||
35
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/try.go
generated
vendored
Normal file
35
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/try.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
package s3
|
||||
import "errors"
|
||||
|
||||
// MaxRetries is the maximum number of retries before bailing.
|
||||
var MaxRetries = 10
|
||||
|
||||
var errMaxRetriesReached = errors.New("exceeded retry limit")
|
||||
|
||||
// Func represents functions that can be retried.
|
||||
type Func func(attempt int) (retry bool, err error)
|
||||
|
||||
// Do keeps trying the function until the second argument
|
||||
// returns false, or no error is returned.
|
||||
func Do(fn Func) error {
|
||||
var err error
|
||||
var cont bool
|
||||
attempt := 1
|
||||
for {
|
||||
cont, err = fn(attempt)
|
||||
if !cont || err == nil {
|
||||
break
|
||||
}
|
||||
attempt++
|
||||
if attempt > MaxRetries {
|
||||
return errMaxRetriesReached
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// IsMaxRetries checks whether the error is due to hitting the
|
||||
// maximum number of retries or not.
|
||||
func IsMaxRetries(err error) bool {
|
||||
return err == errMaxRetriesReached
|
||||
}
|
||||
603
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/uploader.go
generated
vendored
Normal file
603
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/uploader.go
generated
vendored
Normal file
@@ -0,0 +1,603 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/internal/crc"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UploadFileInput struct {
|
||||
// The name of the bucket.
|
||||
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
|
||||
|
||||
// Object key of the object.
|
||||
Key *string `location:"uri" locationName:"Key" type:"string" required:"true"`
|
||||
|
||||
// The path of the file to be uploaded.
|
||||
UploadFile *string `type:"string" required:"true"`
|
||||
|
||||
// The size of the file to be uploaded.
|
||||
FileSize *int64 `type:"integer"`
|
||||
|
||||
// The file part fetcher.
|
||||
FilePartFetcher *FilePartFetcher `type:"structure"`
|
||||
|
||||
// The object metadata.
|
||||
ObjectMeta map[string]*string `type:"structure"`
|
||||
|
||||
// The size of each part.
|
||||
PartSize *int64 `type:"integer"`
|
||||
|
||||
// The number of tasks to upload the file.
|
||||
TaskNum *int64 `type:"integer"`
|
||||
|
||||
// Whether to enable checkpoint.
|
||||
EnableCheckpoint *bool `type:"boolean"`
|
||||
|
||||
// The directory to store the checkpoint file.
|
||||
CheckpointDir *string `type:"string"`
|
||||
|
||||
// The checkpoint file path.
|
||||
CheckpointFile *string `type:"string"`
|
||||
|
||||
// The canned ACL to apply to the object.
|
||||
ACL *string `location:"header" locationName:"x-amz-acl" type:"string"`
|
||||
|
||||
// Specifies caching behavior along the request/reply chain.
|
||||
CacheControl *string `location:"header" locationName:"Cache-Control" type:"string"`
|
||||
|
||||
// Specifies presentational information for the object.
|
||||
ContentDisposition *string `location:"header" locationName:"Content-Disposition" type:"string"`
|
||||
|
||||
// Specifies what content encodings have been applied to the object and thus
|
||||
// what decoding mechanisms must be applied to obtain the media-type referenced
|
||||
// by the Content-Type header field.
|
||||
ContentEncoding *string `location:"header" locationName:"Content-Encoding" type:"string"`
|
||||
|
||||
// A standard MIME type describing the format of the object data.
|
||||
ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
|
||||
|
||||
// The date and time at which the object is no longer cacheable.
|
||||
Expires *time.Time `location:"header" locationName:"Expires" type:"timestamp" timestampFormat:"rfc822"`
|
||||
|
||||
// A map of metadata to store with the object in S3.
|
||||
Metadata map[string]*string `location:"headers" locationName:"x-amz-meta-" type:"map"`
|
||||
|
||||
// The type of storage to use for the object. Defaults to 'STANDARD'.
|
||||
StorageClass *string `location:"header" locationName:"x-amz-storage-class" type:"string"`
|
||||
|
||||
// Specifies the object tag of the object. Multiple tags can be set at the same time, such as: TagA=A&TagB=B.
|
||||
// Note: Key and Value need to be URL-encoded first. If an item does not have "=", the Value is considered to be an empty string.
|
||||
Tagging *string `location:"header" locationName:"x-amz-tagging" type:"string"`
|
||||
|
||||
// Specifies whether the object is forbidden to overwrite.
|
||||
ForbidOverwrite *bool `location:"header" locationName:"x-amz-forbid-overwrite" type:"boolean"`
|
||||
|
||||
// Allows grantee to read the object data and its metadata.
|
||||
GrantRead *string `location:"header" locationName:"x-amz-grant-read" type:"string"`
|
||||
|
||||
// Gives the grantee READ, READ_ACP, and WRITE_ACP permissions on the object.
|
||||
GrantFullControl *string `location:"header" locationName:"x-amz-grant-full-control" type:"string"`
|
||||
|
||||
// The Server-side encryption algorithm used when storing this object in KS3, eg: AES256.
|
||||
ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string"`
|
||||
|
||||
// Specifies the algorithm to use to when encrypting the object, eg: AES256.
|
||||
SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
|
||||
|
||||
// Specifies the customer-provided encryption key for KS3 to use in encrypting data.
|
||||
SSECustomerKey *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key" type:"string"`
|
||||
|
||||
// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
|
||||
SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
|
||||
|
||||
// Progress callback function
|
||||
ProgressFn aws.ProgressFunc `location:"function"`
|
||||
}
|
||||
|
||||
type UploadFileOutput struct {
|
||||
Bucket *string
|
||||
|
||||
Key *string
|
||||
|
||||
ETag *string
|
||||
|
||||
ChecksumCRC64ECMA *string
|
||||
}
|
||||
|
||||
type FilePartFetcher interface {
|
||||
Fetch(objectRange []int64) (io.ReadSeeker, error)
|
||||
}
|
||||
|
||||
func (c *S3) UploadFile(request *UploadFileInput) (*UploadFileOutput, error) {
|
||||
return c.UploadFileWithContext(context.Background(), request)
|
||||
}
|
||||
|
||||
func (c *S3) UploadFileWithContext(ctx context.Context, request *UploadFileInput) (*UploadFileOutput, error) {
|
||||
return newUploader(c, ctx, request).uploadFile()
|
||||
}
|
||||
|
||||
type Uploader struct {
|
||||
client *S3
|
||||
|
||||
context context.Context
|
||||
|
||||
uploadFileRequest *UploadFileInput
|
||||
|
||||
uploadCheckpoint *UploadCheckpoint
|
||||
|
||||
CompletedSize int64
|
||||
|
||||
mu sync.Mutex
|
||||
|
||||
error error
|
||||
}
|
||||
|
||||
func newUploader(s3 *S3, ctx context.Context, request *UploadFileInput) *Uploader {
|
||||
return &Uploader{
|
||||
client: s3,
|
||||
context: ctx,
|
||||
uploadFileRequest: request,
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Uploader) uploadFile() (*UploadFileOutput, error) {
|
||||
err := u.validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if aws.ToString(u.uploadFileRequest.UploadFile) != "" && aws.ToLong(u.uploadFileRequest.FileSize) <= aws.ToLong(u.uploadFileRequest.PartSize) {
|
||||
return u.putObject()
|
||||
}
|
||||
|
||||
return u.multipartUpload()
|
||||
}
|
||||
|
||||
func (u *Uploader) validate() error {
|
||||
request := u.uploadFileRequest
|
||||
if request == nil {
|
||||
return errors.New("upload file request is required")
|
||||
}
|
||||
|
||||
if aws.ToString(request.Bucket) == "" {
|
||||
return errors.New("bucket is required")
|
||||
}
|
||||
|
||||
if aws.ToString(request.Key) == "" {
|
||||
return errors.New("key is required")
|
||||
}
|
||||
|
||||
err := u.normalizeUploadPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
filePath := aws.ToString(request.UploadFile)
|
||||
if filePath == "" && request.FilePartFetcher == nil {
|
||||
return errors.New("upload file or file part fetcher is required")
|
||||
}
|
||||
|
||||
if filePath != "" {
|
||||
fileInfo, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if fileInfo.IsDir() {
|
||||
return errors.New("upload file not a file")
|
||||
}
|
||||
request.FileSize = aws.Long(fileInfo.Size())
|
||||
} else {
|
||||
if request.ObjectMeta != nil {
|
||||
fileSize, _ := strconv.ParseInt(aws.ToString(request.ObjectMeta[HTTPHeaderContentLength]), 10, 64)
|
||||
request.FileSize = aws.Long(fileSize)
|
||||
}
|
||||
}
|
||||
|
||||
if request.FilePartFetcher != nil && request.FileSize == nil {
|
||||
return errors.New("file size is required")
|
||||
}
|
||||
|
||||
if request.PartSize == nil {
|
||||
request.PartSize = aws.Long(DefaultPartSize)
|
||||
} else if aws.ToLong(request.PartSize) < MinPartSize {
|
||||
request.PartSize = aws.Long(MinPartSize)
|
||||
} else if aws.ToLong(request.PartSize) > MaxPartSize {
|
||||
request.PartSize = aws.Long(MaxPartSize)
|
||||
}
|
||||
|
||||
if aws.ToLong(request.TaskNum) <= 0 {
|
||||
request.TaskNum = aws.Long(DefaultTaskNum)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *Uploader) putObject() (*UploadFileOutput, error) {
|
||||
request := u.uploadFileRequest
|
||||
fd, err := os.Open(aws.ToString(request.UploadFile))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
resp, err := u.client.PutObjectWithContext(u.context, &PutObjectInput{
|
||||
Bucket: request.Bucket,
|
||||
Key: request.Key,
|
||||
Body: fd,
|
||||
ACL: request.ACL,
|
||||
CacheControl: request.CacheControl,
|
||||
ContentDisposition: request.ContentDisposition,
|
||||
ContentEncoding: request.ContentEncoding,
|
||||
ContentType: request.ContentType,
|
||||
Expires: request.Expires,
|
||||
Metadata: request.Metadata,
|
||||
StorageClass: request.StorageClass,
|
||||
Tagging: request.Tagging,
|
||||
ForbidOverwrite: request.ForbidOverwrite,
|
||||
GrantRead: request.GrantRead,
|
||||
GrantFullControl: request.GrantFullControl,
|
||||
ServerSideEncryption: request.ServerSideEncryption,
|
||||
SSECustomerAlgorithm: request.SSECustomerAlgorithm,
|
||||
SSECustomerKey: request.SSECustomerKey,
|
||||
SSECustomerKeyMD5: request.SSECustomerKeyMD5,
|
||||
ProgressFn: request.ProgressFn,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &UploadFileOutput{
|
||||
Bucket: request.Bucket,
|
||||
Key: request.Key,
|
||||
ETag: resp.ETag,
|
||||
ChecksumCRC64ECMA: resp.Metadata[HTTPHeaderAmzChecksumCrc64ecma],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (u *Uploader) multipartUpload() (*UploadFileOutput, error) {
|
||||
ucp, err := newUploadCheckpoint(u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u.uploadCheckpoint = ucp
|
||||
|
||||
if aws.ToBoolean(u.uploadFileRequest.EnableCheckpoint) {
|
||||
cpFilePath := aws.ToString(u.uploadFileRequest.CheckpointFile)
|
||||
if cpFilePath == "" {
|
||||
cpFilePath, err = generateUploadCpFilePath(u.uploadFileRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
ucp.CpFilePath = cpFilePath
|
||||
|
||||
err = ucp.load()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ucp.UploadId != "" && !u.isUploadIdValid() {
|
||||
ucp.UploadId = ""
|
||||
ucp.PartETagList = make([]*CompletedPart, 0)
|
||||
ucp.remove()
|
||||
}
|
||||
}
|
||||
|
||||
if ucp.UploadId == "" {
|
||||
ucp.UploadId, err = u.initUploadId()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ucp.dump()
|
||||
}
|
||||
|
||||
fileSize := ucp.UploadFileSize
|
||||
partSize := ucp.PartSize
|
||||
totalPartNum := (fileSize-1)/partSize + 1
|
||||
tasks := make(chan UploadPartTask, totalPartNum)
|
||||
|
||||
var i int64
|
||||
for i = 0; i < totalPartNum; i++ {
|
||||
partNum := i + 1
|
||||
offset := i * partSize
|
||||
actualPartSize := u.getActualPartSize(fileSize, partSize, partNum)
|
||||
partETag := u.getPartETag(partNum)
|
||||
if partETag != nil {
|
||||
u.publishProgress(actualPartSize)
|
||||
} else {
|
||||
uploadPartTask := UploadPartTask{
|
||||
partNumber: partNum,
|
||||
offset: offset,
|
||||
actualPartSize: actualPartSize,
|
||||
}
|
||||
tasks <- uploadPartTask
|
||||
}
|
||||
}
|
||||
close(tasks)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for i = 0; i < aws.ToLong(u.uploadFileRequest.TaskNum); i++ {
|
||||
wg.Add(1)
|
||||
go u.runTask(tasks, &wg)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
if u.error != nil {
|
||||
return nil, u.error
|
||||
}
|
||||
|
||||
completedMultipartUpload := u.getMultipartUploadParts()
|
||||
resp, err := u.completeMultipartUpload(completedMultipartUpload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if u.client.Config.CrcCheckEnabled {
|
||||
clientCrc64 := u.getCrc64Ecma(completedMultipartUpload.Parts)
|
||||
serverCrc64, _ := strconv.ParseUint(aws.ToString(resp.ChecksumCRC64ECMA), 10, 64)
|
||||
u.client.Config.LogDebug("check file crc64, client crc64:%d, server crc64:%d", clientCrc64, serverCrc64)
|
||||
if serverCrc64 != 0 && clientCrc64 != serverCrc64 {
|
||||
return nil, errors.New(fmt.Sprintf("crc64 check failed, client crc64:%d, server crc64:%d", clientCrc64, serverCrc64))
|
||||
}
|
||||
}
|
||||
|
||||
return u.getUploadFileOutput(resp), nil
|
||||
}
|
||||
|
||||
func (u *Uploader) getUploadFileOutput(resp *CompleteMultipartUploadOutput) *UploadFileOutput {
|
||||
return &UploadFileOutput{
|
||||
Bucket: resp.Bucket,
|
||||
Key: resp.Key,
|
||||
ETag: resp.ETag,
|
||||
ChecksumCRC64ECMA: resp.ChecksumCRC64ECMA,
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Uploader) getPartSize(fileSize int64, originPartSize int64) int64 {
|
||||
partSize := originPartSize
|
||||
totalPartNum := (fileSize-1)/partSize + 1
|
||||
for totalPartNum > MaxPartNum {
|
||||
partSize += originPartSize
|
||||
totalPartNum = (fileSize-1)/partSize + 1
|
||||
}
|
||||
return partSize
|
||||
}
|
||||
|
||||
func (u *Uploader) getActualPartSize(fileSize int64, partSize int64, partNum int64) int64 {
|
||||
offset := (partNum - 1) * partSize
|
||||
actualPartSize := partSize
|
||||
if offset+partSize >= fileSize {
|
||||
actualPartSize = fileSize - offset
|
||||
}
|
||||
return actualPartSize
|
||||
}
|
||||
|
||||
func (u *Uploader) getPartETag(partNumber int64) *CompletedPart {
|
||||
for _, partETag := range u.uploadCheckpoint.PartETagList {
|
||||
if *partETag.PartNumber == partNumber {
|
||||
return partETag
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type UploadPartTask struct {
|
||||
partNumber int64
|
||||
|
||||
offset int64
|
||||
|
||||
actualPartSize int64
|
||||
}
|
||||
|
||||
func (u *Uploader) runTask(tasks <-chan UploadPartTask, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
for task := range tasks {
|
||||
if u.error != nil {
|
||||
return
|
||||
}
|
||||
|
||||
partETag, err := u.uploadPart(task)
|
||||
if err != nil {
|
||||
u.setError(err)
|
||||
return
|
||||
}
|
||||
|
||||
u.updatePart(partETag)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Uploader) uploadPart(task UploadPartTask) (CompletedPart, error) {
|
||||
request := u.uploadFileRequest
|
||||
ucp := u.uploadCheckpoint
|
||||
offset := task.offset
|
||||
actualPartSize := task.actualPartSize
|
||||
var partETag CompletedPart
|
||||
var reader io.ReadSeeker
|
||||
if ucp.UploadFilePath != "" {
|
||||
fd, err := os.Open(ucp.UploadFilePath)
|
||||
if err != nil {
|
||||
return partETag, err
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
reader = io.NewSectionReader(fd, offset, actualPartSize)
|
||||
} else {
|
||||
var err error
|
||||
reader, err = (*u.uploadFileRequest.FilePartFetcher).Fetch([]int64{offset, offset + actualPartSize - 1})
|
||||
if err != nil {
|
||||
return partETag, err
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := u.client.UploadPartWithContext(u.context, &UploadPartInput{
|
||||
Bucket: aws.String(ucp.BucketName),
|
||||
Key: aws.String(ucp.ObjectKey),
|
||||
UploadID: aws.String(ucp.UploadId),
|
||||
PartNumber: aws.Long(task.partNumber),
|
||||
Body: reader,
|
||||
ContentLength: aws.Long(actualPartSize),
|
||||
SSECustomerAlgorithm: request.SSECustomerAlgorithm,
|
||||
SSECustomerKey: request.SSECustomerKey,
|
||||
SSECustomerKeyMD5: request.SSECustomerKeyMD5,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return partETag, err
|
||||
}
|
||||
|
||||
partETag.PartNumber = aws.Long(task.partNumber)
|
||||
partETag.ETag = resp.ETag
|
||||
partETag.ChecksumCRC64ECMA = resp.ChecksumCRC64ECMA
|
||||
u.publishProgress(actualPartSize)
|
||||
|
||||
return partETag, nil
|
||||
}
|
||||
|
||||
func (u *Uploader) updatePart(partETag CompletedPart) {
|
||||
u.mu.Lock()
|
||||
defer u.mu.Unlock()
|
||||
|
||||
u.uploadCheckpoint.PartETagList = append(u.uploadCheckpoint.PartETagList, &partETag)
|
||||
u.uploadCheckpoint.dump()
|
||||
}
|
||||
|
||||
func (u *Uploader) setError(err error) {
|
||||
u.mu.Lock()
|
||||
defer u.mu.Unlock()
|
||||
|
||||
if u.error == nil {
|
||||
u.error = err
|
||||
}
|
||||
}
|
||||
|
||||
type CompletedParts []*CompletedPart
|
||||
|
||||
func (cp CompletedParts) Len() int {
|
||||
return len(cp)
|
||||
}
|
||||
|
||||
func (cp CompletedParts) Less(i, j int) bool {
|
||||
return *cp[i].PartNumber < *cp[j].PartNumber
|
||||
}
|
||||
|
||||
func (cp CompletedParts) Swap(i, j int) {
|
||||
cp[i], cp[j] = cp[j], cp[i]
|
||||
}
|
||||
|
||||
func (u *Uploader) getMultipartUploadParts() *CompletedMultipartUpload {
|
||||
partETags := u.uploadCheckpoint.PartETagList
|
||||
// 按照PartNumber排序
|
||||
sort.Sort(CompletedParts(partETags))
|
||||
return &CompletedMultipartUpload{
|
||||
Parts: partETags,
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Uploader) completeMultipartUpload(completedMultipartUpload *CompletedMultipartUpload) (*CompleteMultipartUploadOutput, error) {
|
||||
resp, err := u.client.CompleteMultipartUploadWithContext(u.context, &CompleteMultipartUploadInput{
|
||||
Bucket: u.uploadFileRequest.Bucket,
|
||||
Key: u.uploadFileRequest.Key,
|
||||
UploadID: aws.String(u.uploadCheckpoint.UploadId),
|
||||
MultipartUpload: completedMultipartUpload,
|
||||
ForbidOverwrite: u.uploadFileRequest.ForbidOverwrite,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u.uploadCheckpoint.remove()
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (u *Uploader) publishProgress(actualPartSize int64) {
|
||||
if u.uploadFileRequest.ProgressFn != nil {
|
||||
atomic.AddInt64(&u.CompletedSize, actualPartSize)
|
||||
u.uploadFileRequest.ProgressFn(actualPartSize, u.CompletedSize, aws.ToLong(u.uploadFileRequest.FileSize))
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Uploader) getCrc64Ecma(parts []*CompletedPart) uint64 {
|
||||
if parts == nil || len(parts) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
fileSize := u.uploadCheckpoint.UploadFileSize
|
||||
partSize := u.uploadCheckpoint.PartSize
|
||||
|
||||
crcTemp, _ := strconv.ParseUint(*parts[0].ChecksumCRC64ECMA, 10, 64)
|
||||
for i := 1; i < len(parts); i++ {
|
||||
crc2, _ := strconv.ParseUint(*parts[i].ChecksumCRC64ECMA, 10, 64)
|
||||
actualPartSize := u.getActualPartSize(fileSize, partSize, *parts[i].PartNumber)
|
||||
crcTemp = crc.CRC64Combine(crcTemp, crc2, (uint64)(actualPartSize))
|
||||
}
|
||||
|
||||
return crcTemp
|
||||
}
|
||||
|
||||
func (u *Uploader) initUploadId() (string, error) {
|
||||
request := u.uploadFileRequest
|
||||
resp, err := u.client.CreateMultipartUploadWithContext(u.context, &CreateMultipartUploadInput{
|
||||
Bucket: request.Bucket,
|
||||
Key: request.Key,
|
||||
ACL: request.ACL,
|
||||
CacheControl: request.CacheControl,
|
||||
ContentDisposition: request.ContentDisposition,
|
||||
ContentEncoding: request.ContentEncoding,
|
||||
ContentType: request.ContentType,
|
||||
Expires: request.Expires,
|
||||
Metadata: request.Metadata,
|
||||
StorageClass: request.StorageClass,
|
||||
Tagging: request.Tagging,
|
||||
ForbidOverwrite: request.ForbidOverwrite,
|
||||
GrantRead: request.GrantRead,
|
||||
GrantFullControl: request.GrantFullControl,
|
||||
ServerSideEncryption: request.ServerSideEncryption,
|
||||
SSECustomerAlgorithm: request.SSECustomerAlgorithm,
|
||||
SSECustomerKey: request.SSECustomerKey,
|
||||
SSECustomerKeyMD5: request.SSECustomerKeyMD5,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return aws.ToString(resp.UploadID), nil
|
||||
}
|
||||
|
||||
func (u *Uploader) isUploadIdValid() bool {
|
||||
_, err := u.client.ListPartsWithContext(u.context, &ListPartsInput{
|
||||
Bucket: u.uploadFileRequest.Bucket,
|
||||
Key: u.uploadFileRequest.Key,
|
||||
UploadID: aws.String(u.uploadCheckpoint.UploadId),
|
||||
})
|
||||
if err != nil && strings.Contains(err.Error(), "NoSuchUpload") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (u *Uploader) normalizeUploadPath() error {
|
||||
uploadPath := aws.ToString(u.uploadFileRequest.UploadFile)
|
||||
if uploadPath == "" {
|
||||
return nil
|
||||
}
|
||||
// 规范化路径
|
||||
normalizedPath := filepath.Clean(uploadPath)
|
||||
// 获取绝对路径
|
||||
absPath, err := filepath.Abs(normalizedPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.uploadFileRequest.UploadFile = aws.String(absPath)
|
||||
|
||||
return nil
|
||||
}
|
||||
108
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/util.go
generated
vendored
Normal file
108
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/util.go
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
)
|
||||
|
||||
// GetBase64MD5Str 计算Base64格式字符串的MD5值
|
||||
func GetBase64MD5Str(str string) string {
|
||||
// 创建一个MD5哈希对象
|
||||
hash := md5.New()
|
||||
|
||||
// 将字符串转换为字节数组并计算MD5哈希值
|
||||
hash.Write([]byte(str))
|
||||
md5Hash := hash.Sum(nil)
|
||||
|
||||
// 将MD5哈希值转换为Base64格式
|
||||
base64Str := base64.StdEncoding.EncodeToString(md5Hash)
|
||||
|
||||
return base64Str
|
||||
}
|
||||
|
||||
// GetBase64Str 计算Base64格式字符串
|
||||
func GetBase64Str(str string) string {
|
||||
return base64.StdEncoding.EncodeToString([]byte(str))
|
||||
}
|
||||
|
||||
// GetBase64FileMD5Str 计算Base64格式文件的MD5值
|
||||
func GetBase64FileMD5Str(filePath string) (string, error) {
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
hash := md5.New()
|
||||
if _, err := io.Copy(hash, file); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
md5Hash := hash.Sum(nil)
|
||||
|
||||
// 将MD5哈希值转换为Base64格式
|
||||
base64Str := base64.StdEncoding.EncodeToString(md5Hash)
|
||||
|
||||
return base64Str, err
|
||||
}
|
||||
|
||||
// BuildCopySource 构建拷贝源
|
||||
func BuildCopySource(bucket *string, key *string) string {
|
||||
if bucket == nil || key == nil {
|
||||
return ""
|
||||
}
|
||||
return "/" + *bucket + "/" + url.QueryEscape(*key)
|
||||
}
|
||||
|
||||
// GetCannedACL 获取访问控制权限
|
||||
func GetCannedACL(Grants []*Grant) string {
|
||||
allUsersPermissions := map[string]*string{}
|
||||
for _, value := range Grants {
|
||||
if value.Grantee.URI != nil && *value.Grantee.URI == AllUsersUri {
|
||||
allUsersPermissions[*value.Permission] = value.Permission
|
||||
}
|
||||
}
|
||||
_, read := allUsersPermissions["READ"]
|
||||
_, write := allUsersPermissions["WRITE"]
|
||||
if read && write {
|
||||
return ACLPublicReadWrite
|
||||
} else if read {
|
||||
return ACLPublicRead
|
||||
} else {
|
||||
return ACLPrivate
|
||||
}
|
||||
}
|
||||
|
||||
// FileExists returns whether the given file exists or not
|
||||
func FileExists(filename string) bool {
|
||||
info, err := os.Stat(filename)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return !info.IsDir()
|
||||
}
|
||||
|
||||
// DirExists returns whether the given directory exists or not
|
||||
func DirExists(dir string) bool {
|
||||
info, err := os.Stat(dir)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return info.IsDir()
|
||||
}
|
||||
|
||||
// Min returns the smaller of two integers
|
||||
func Min(a, b int64) int64 {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// IsV4Signature checks if the signer is V4 or V4_UNSIGNED_PAYLOAD_SIGNER
|
||||
func IsV4Signature(signer string) bool {
|
||||
return signer == "V4" || signer == "V4_UNSIGNED_PAYLOAD_SIGNER"
|
||||
}
|
||||
206
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/vpc_access_block.go
generated
vendored
Normal file
206
vendor/github.com/ks3sdklib/aws-sdk-go/service/s3/vpc_access_block.go
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PutVpcAccessBlockInput struct {
|
||||
// Vpc access block configuration container.
|
||||
VpcAccessBlockConfiguration *VpcAccessBlockConfiguration `locationName:"VpcAccessBlockConfiguration" type:"structure" required:"true"`
|
||||
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
|
||||
metadataPutVpcAccessBlockInput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataPutVpcAccessBlockInput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"VpcAccessBlockConfiguration"`
|
||||
|
||||
AutoFillMD5 bool
|
||||
}
|
||||
|
||||
type VpcAccessBlockConfiguration struct {
|
||||
// Set up VPC to access the KS3 public Region rules container.
|
||||
Rules []*VpcAccessBlockRule `locationName:"Rule" type:"list" flattened:"true" required:"true"`
|
||||
}
|
||||
|
||||
type VpcAccessBlockRule struct {
|
||||
// The unique identifier of a Rule. The ID cannot be repeated in a rule.
|
||||
RuleID *string `locationName:"RuleID" type:"string" required:"true"`
|
||||
|
||||
// Region to which the VPC belongs.
|
||||
Region *string `locationName:"Region" type:"string" required:"true"`
|
||||
|
||||
// Set the VPC ID of the container.
|
||||
VPC *VPC `locationName:"VPC" type:"structure"`
|
||||
|
||||
// Set the bucket's container.
|
||||
BucketAllowAccess *BucketAllowAccess `locationName:"BucketAllowAccess" type:"structure"`
|
||||
|
||||
// Whether to enable this rule.
|
||||
Status *string `locationName:"Status" type:"string" required:"true"`
|
||||
|
||||
// Creation time.
|
||||
CreationDate *time.Time `locationName:"CreationDate" type:"timestamp" timestampFormat:"iso8601"`
|
||||
}
|
||||
|
||||
type VPC struct {
|
||||
// List of VPC IDs that are not allowed to access resources in this Region.
|
||||
IDs []string `locationName:"ID" type:"list" flattened:"true"`
|
||||
}
|
||||
|
||||
type BucketAllowAccess struct {
|
||||
// List of Bucket names that are allowed to be accessed.
|
||||
Names []string `locationName:"Name" type:"list" flattened:"true"`
|
||||
}
|
||||
|
||||
type PutVpcAccessBlockOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// PutVpcAccessBlockRequest generates a request for the PutVpcAccessBlock operation.
|
||||
func (c *S3) PutVpcAccessBlockRequest(input *PutVpcAccessBlockInput) (req *aws.Request, output *PutVpcAccessBlockOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "PutVpcAccessBlock",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/?VpcAccessBlock",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &PutVpcAccessBlockInput{}
|
||||
}
|
||||
|
||||
input.AutoFillMD5 = true
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &PutVpcAccessBlockOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// PutVpcAccessBlock sets vpc access block configuration.
|
||||
func (c *S3) PutVpcAccessBlock(input *PutVpcAccessBlockInput) (*PutVpcAccessBlockOutput, error) {
|
||||
req, out := c.PutVpcAccessBlockRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) PutVpcAccessBlockWithContext(ctx aws.Context, input *PutVpcAccessBlockInput) (*PutVpcAccessBlockOutput, error) {
|
||||
req, out := c.PutVpcAccessBlockRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type GetVpcAccessBlockInput struct {
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type GetVpcAccessBlockOutput struct {
|
||||
// Vpc access block configuration container.
|
||||
VpcAccessBlockConfiguration *VpcAccessBlockConfiguration `locationName:"VpcAccessBlockConfiguration" type:"structure"`
|
||||
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
|
||||
metadataGetVpcAccessBlockOutput `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
type metadataGetVpcAccessBlockOutput struct {
|
||||
SDKShapeTraits bool `type:"structure" payload:"VpcAccessBlockConfiguration"`
|
||||
}
|
||||
|
||||
// GetVpcAccessBlockRequest generates a request for the GetVpcAccessBlock operation.
|
||||
func (c *S3) GetVpcAccessBlockRequest(input *GetVpcAccessBlockInput) (req *aws.Request, output *GetVpcAccessBlockOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "GetVpcAccessBlock",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: "/?VpcAccessBlock",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &GetVpcAccessBlockInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &GetVpcAccessBlockOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// GetVpcAccessBlock gets vpc access block configuration.
|
||||
func (c *S3) GetVpcAccessBlock(input *GetVpcAccessBlockInput) (*GetVpcAccessBlockOutput, error) {
|
||||
req, out := c.GetVpcAccessBlockRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) GetVpcAccessBlockWithContext(ctx aws.Context, input *GetVpcAccessBlockInput) (*GetVpcAccessBlockOutput, error) {
|
||||
req, out := c.GetVpcAccessBlockRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
type DeleteVpcAccessBlockInput struct {
|
||||
// Set extend request headers. If the existing fields do not support setting the request header you need, you can set it through this field.
|
||||
ExtendHeaders map[string]*string `location:"extendHeaders" type:"map"`
|
||||
|
||||
// Set extend query params. If the existing fields do not support setting the query param you need, you can set it through this field.
|
||||
ExtendQueryParams map[string]*string `location:"extendQueryParams" type:"map"`
|
||||
}
|
||||
|
||||
type DeleteVpcAccessBlockOutput struct {
|
||||
// The HTTP headers of the response.
|
||||
Metadata map[string]*string `location:"headers" type:"map"`
|
||||
|
||||
// The HTTP status code of the response.
|
||||
StatusCode *int64 `location:"statusCode" type:"integer"`
|
||||
}
|
||||
|
||||
// DeleteVpcAccessBlockRequest generates a request for the DeleteVpcAccessBlock operation.
|
||||
func (c *S3) DeleteVpcAccessBlockRequest(input *DeleteVpcAccessBlockInput) (req *aws.Request, output *DeleteVpcAccessBlockOutput) {
|
||||
op := &aws.Operation{
|
||||
Name: "DeleteVpcAccessBlock",
|
||||
HTTPMethod: "DELETE",
|
||||
HTTPPath: "/?VpcAccessBlock",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &DeleteVpcAccessBlockInput{}
|
||||
}
|
||||
|
||||
req = c.newRequest(op, input, output)
|
||||
output = &DeleteVpcAccessBlockOutput{}
|
||||
req.Data = output
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteVpcAccessBlock deletes vpc access block configuration.
|
||||
func (c *S3) DeleteVpcAccessBlock(input *DeleteVpcAccessBlockInput) (*DeleteVpcAccessBlockOutput, error) {
|
||||
req, out := c.DeleteVpcAccessBlockRequest(input)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *S3) DeleteVpcAccessBlockWithContext(ctx aws.Context, input *DeleteVpcAccessBlockInput) (*DeleteVpcAccessBlockOutput, error) {
|
||||
req, out := c.DeleteVpcAccessBlockRequest(input)
|
||||
req.SetContext(ctx)
|
||||
err := req.Send()
|
||||
return out, err
|
||||
}
|
||||
27
vendor/modules.txt
vendored
27
vendor/modules.txt
vendored
@@ -849,6 +849,29 @@ github.com/koding/websocketproxy
|
||||
# github.com/kr/fs v0.1.0
|
||||
## explicit
|
||||
github.com/kr/fs
|
||||
# github.com/ks3sdklib/aws-sdk-go v1.8.1
|
||||
## explicit; go 1.16
|
||||
github.com/ks3sdklib/aws-sdk-go/aws
|
||||
github.com/ks3sdklib/aws-sdk-go/aws/awserr
|
||||
github.com/ks3sdklib/aws-sdk-go/aws/awsutil
|
||||
github.com/ks3sdklib/aws-sdk-go/aws/credentials
|
||||
github.com/ks3sdklib/aws-sdk-go/aws/retry
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/apierr
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/crc
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/endpoints
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/protocol/body
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/protocol/json/jsonutil
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/protocol/jsonrpc
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/protocol/query
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/protocol/query/queryutil
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/protocol/rest
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/protocol/restjson
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/protocol/restxml
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/protocol/xml/xmlutil
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/signer/open_api
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/signer/v2
|
||||
github.com/ks3sdklib/aws-sdk-go/internal/signer/v4
|
||||
github.com/ks3sdklib/aws-sdk-go/service/s3
|
||||
# github.com/leodido/go-urn v1.2.0
|
||||
## explicit; go 1.13
|
||||
github.com/leodido/go-urn
|
||||
@@ -1877,7 +1900,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
|
||||
# sigs.k8s.io/yaml v1.2.0
|
||||
## explicit; go 1.12
|
||||
sigs.k8s.io/yaml
|
||||
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250915054625-7251d9eeceec
|
||||
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250924031606-a2597eb1f66f
|
||||
## explicit; go 1.24
|
||||
yunion.io/x/cloudmux/pkg/apis
|
||||
yunion.io/x/cloudmux/pkg/apis/billing
|
||||
@@ -2028,7 +2051,7 @@ yunion.io/x/pkg/utils
|
||||
# yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1
|
||||
## explicit; go 1.12
|
||||
yunion.io/x/s3cli
|
||||
# yunion.io/x/sqlchemy v1.1.3-0.20250902120005-3b18bc6371c7
|
||||
# yunion.io/x/sqlchemy v1.1.3-0.20250923143347-b98e89dbc372
|
||||
## explicit; go 1.17
|
||||
yunion.io/x/sqlchemy
|
||||
yunion.io/x/sqlchemy/backends
|
||||
|
||||
11
vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/dbinstance_cluster.go
generated
vendored
11
vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/dbinstance_cluster.go
generated
vendored
@@ -231,7 +231,16 @@ func (rds *SDBInstanceCluster) GetIDBInstanceAccounts() ([]cloudprovider.ICloudD
|
||||
}
|
||||
|
||||
func (rds *SDBInstanceCluster) GetIDBInstanceBackups() ([]cloudprovider.ICloudDBInstanceBackup, error) {
|
||||
return nil, cloudprovider.ErrNotSupported
|
||||
ret := []cloudprovider.ICloudDBInstanceBackup{}
|
||||
backups, err := rds.region.DescribeDBClusterSnapshots(rds.DBClusterIdentifier, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range backups {
|
||||
backups[i].region = rds.region
|
||||
ret = append(ret, &backups[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (rds *SDBInstanceCluster) ChangeConfig(ctx context.Context, config *cloudprovider.SManagedDBInstanceChangeConfig) error {
|
||||
|
||||
172
vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/dbinstance_cluster_snapshots.go
generated
vendored
Normal file
172
vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/dbinstance_cluster_snapshots.go
generated
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package aws
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
api "yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/cloudmux/pkg/multicloud"
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
type SDBInstanceClusterSnapshot struct {
|
||||
multicloud.SDBInstanceBackupBase
|
||||
AwsTags
|
||||
|
||||
region *SRegion
|
||||
|
||||
AllocatedStorage int `xml:"AllocatedStorage"`
|
||||
AvailabilityZones []string `xml:"AvailabilityZones>AvailabilityZone"`
|
||||
EngineMode string `xml:"EngineMode"`
|
||||
Engine string `xml:"Engine"`
|
||||
PercentProgress int `xml:"PercentProgress"`
|
||||
VpcId string `xml:"VpcId"`
|
||||
IAMDatabaseAuthenticationEnabled bool `xml:"IAMDatabaseAuthenticationEnabled"`
|
||||
DBClusterSnapshotIdentifier string `xml:"DBClusterSnapshotIdentifier"`
|
||||
ClusterCreateTime time.Time `xml:"ClusterCreateTime"`
|
||||
EngineVersion string `xml:"EngineVersion"`
|
||||
MasterUsername string `xml:"MasterUsername"`
|
||||
SnapshotType string `xml:"SnapshotType"`
|
||||
StorageEncrypted bool `xml:"StorageEncrypted"`
|
||||
TagList []struct {
|
||||
Value string `xml:"Value"`
|
||||
Key string `xml:"Key"`
|
||||
} `xml:"TagList>Tag"`
|
||||
Port int `xml:"Port"`
|
||||
SnapshotCreateTime time.Time `xml:"SnapshotCreateTime"`
|
||||
LicenseModel string `xml:"LicenseModel"`
|
||||
KmsKeyId string `xml:"KmsKeyId"`
|
||||
DBClusterIdentifier string `xml:"DBClusterIdentifier"`
|
||||
DBClusterSnapshotArn string `xml:"DBClusterSnapshotArn"`
|
||||
DbClusterResourceId string `xml:"DbClusterResourceId"`
|
||||
Status string `xml:"Status"`
|
||||
}
|
||||
|
||||
func (snapshot *SDBInstanceClusterSnapshot) GetId() string {
|
||||
return snapshot.DBClusterSnapshotArn
|
||||
}
|
||||
|
||||
func (snapshot *SDBInstanceClusterSnapshot) GetGlobalId() string {
|
||||
return snapshot.DBClusterSnapshotArn
|
||||
}
|
||||
|
||||
func (snapshot *SDBInstanceClusterSnapshot) GetName() string {
|
||||
return snapshot.DBClusterSnapshotIdentifier
|
||||
}
|
||||
|
||||
func (snapshot *SDBInstanceClusterSnapshot) GetEngine() string {
|
||||
return snapshot.Engine
|
||||
}
|
||||
|
||||
func (snapshot *SDBInstanceClusterSnapshot) GetEngineVersion() string {
|
||||
return snapshot.EngineVersion
|
||||
}
|
||||
|
||||
func (snapshot *SDBInstanceClusterSnapshot) GetStartTime() time.Time {
|
||||
return snapshot.SnapshotCreateTime
|
||||
}
|
||||
|
||||
func (snapshot *SDBInstanceClusterSnapshot) GetEndTime() time.Time {
|
||||
return snapshot.SnapshotCreateTime
|
||||
}
|
||||
|
||||
func (snapshot *SDBInstanceClusterSnapshot) GetBackupMode() string {
|
||||
switch snapshot.SnapshotType {
|
||||
case "manual":
|
||||
return api.BACKUP_MODE_MANUAL
|
||||
default:
|
||||
return api.BACKUP_MODE_AUTOMATED
|
||||
}
|
||||
}
|
||||
|
||||
func (snapshot *SDBInstanceClusterSnapshot) GetStatus() string {
|
||||
switch snapshot.Status {
|
||||
case "available":
|
||||
return api.DBINSTANCE_BACKUP_READY
|
||||
default:
|
||||
log.Errorf("unknown dbinstance snapshot status: %s", snapshot.Status)
|
||||
return api.DBINSTANCE_BACKUP_UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SDBInstanceClusterSnapshot) Refresh() error {
|
||||
snap, err := self.region.GetDBClusterSnapshot(self.DBClusterSnapshotIdentifier)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return jsonutils.Update(self, snap)
|
||||
}
|
||||
|
||||
func (snapshot *SDBInstanceClusterSnapshot) GetBackupSizeMb() int {
|
||||
return snapshot.AllocatedStorage * 1024
|
||||
}
|
||||
|
||||
func (snapshot *SDBInstanceClusterSnapshot) GetDBNames() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (snapshot *SDBInstanceClusterSnapshot) GetDBInstanceId() string {
|
||||
return snapshot.DBClusterIdentifier
|
||||
}
|
||||
|
||||
func (self *SDBInstanceClusterSnapshot) Delete() error {
|
||||
return self.region.DeleteRdsSnapshot(self.DBClusterSnapshotIdentifier)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetDBClusterSnapshot(id string) (*SDBInstanceClusterSnapshot, error) {
|
||||
snapshots, err := self.DescribeDBClusterSnapshots("", id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range snapshots {
|
||||
if snapshots[i].GetGlobalId() == id {
|
||||
return &snapshots[i], nil
|
||||
}
|
||||
}
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", id)
|
||||
}
|
||||
|
||||
func (region *SRegion) DescribeDBClusterSnapshots(clusterId, snapshotId string) ([]SDBInstanceClusterSnapshot, error) {
|
||||
params := map[string]string{}
|
||||
if len(clusterId) > 0 {
|
||||
params["DBClusterIdentifier"] = clusterId
|
||||
}
|
||||
if len(snapshotId) > 0 {
|
||||
params["DBClusterSnapshotIdentifier"] = snapshotId
|
||||
}
|
||||
ret := []SDBInstanceClusterSnapshot{}
|
||||
for {
|
||||
part := struct {
|
||||
DBClusterSnapshots struct {
|
||||
DBClusterSnapshot []SDBInstanceClusterSnapshot `xml:"DBClusterSnapshot"`
|
||||
}
|
||||
Marker string `xml:"Marker"`
|
||||
}{}
|
||||
err := region.rdsRequest("DescribeDBClusterSnapshots", params, &part)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = append(ret, part.DBClusterSnapshots.DBClusterSnapshot...)
|
||||
if len(part.DBClusterSnapshots.DBClusterSnapshot) == 0 || len(part.Marker) == 0 {
|
||||
break
|
||||
}
|
||||
params["Marker"] = part.Marker
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
8
vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/dbinstance_snapshot.go
generated
vendored
8
vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/dbinstance_snapshot.go
generated
vendored
@@ -190,5 +190,13 @@ func (region *SRegion) GetIDBInstanceBackups() ([]cloudprovider.ICloudDBInstance
|
||||
snapshots[i].region = region
|
||||
isnapshots = append(isnapshots, &snapshots[i])
|
||||
}
|
||||
clusterSnapshots, err := region.DescribeDBClusterSnapshots("", "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "DescribeDBClusterSnapshots")
|
||||
}
|
||||
for i := 0; i < len(clusterSnapshots); i++ {
|
||||
clusterSnapshots[i].region = region
|
||||
isnapshots = append(isnapshots, &clusterSnapshots[i])
|
||||
}
|
||||
return isnapshots, nil
|
||||
}
|
||||
|
||||
2
vendor/yunion.io/x/cloudmux/pkg/multicloud/google/instance.go
generated
vendored
2
vendor/yunion.io/x/cloudmux/pkg/multicloud/google/instance.go
generated
vendored
@@ -616,7 +616,7 @@ func (region *SRegion) _createVM(zone string, desc *cloudprovider.SManagedVMCrea
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "region.GetNetwork")
|
||||
}
|
||||
networkInterface["network"] = vpc.SelfLink
|
||||
networkInterface["subnetwork"] = getGlobalId(vpc.SelfLink)
|
||||
}
|
||||
if len(desc.IpAddr) > 0 {
|
||||
networkInterface["networkIp"] = desc.IpAddr
|
||||
|
||||
599
vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/bucket.go
generated
vendored
Normal file
599
vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/bucket.go
generated
vendored
Normal file
@@ -0,0 +1,599 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ksyun
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws"
|
||||
"github.com/ks3sdklib/aws-sdk-go/aws/credentials"
|
||||
"github.com/ks3sdklib/aws-sdk-go/service/s3"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/fileutils"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/cloudmux/pkg/multicloud"
|
||||
)
|
||||
|
||||
type SBucket struct {
|
||||
multicloud.SBaseBucket
|
||||
SKsyunTags
|
||||
|
||||
region *SRegion
|
||||
|
||||
CreationDate time.Time
|
||||
Name string
|
||||
Region string
|
||||
Type string
|
||||
VisitType string
|
||||
DataRedundancyType string
|
||||
}
|
||||
|
||||
func (b *SBucket) GetProjectId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (b *SBucket) GetGlobalId() string {
|
||||
return b.Name
|
||||
}
|
||||
|
||||
func (b *SBucket) GetName() string {
|
||||
return b.Name
|
||||
}
|
||||
|
||||
func (b *SBucket) GetAcl() cloudprovider.TBucketACLType {
|
||||
return b.region.GetBucketAcl(b.Name)
|
||||
}
|
||||
|
||||
func (region *SRegion) GetBucketAcl(bucket string) cloudprovider.TBucketACLType {
|
||||
svc := region.getS3Client()
|
||||
input := &s3.GetBucketACLInput{
|
||||
Bucket: &bucket,
|
||||
}
|
||||
resp, err := svc.GetBucketACL(input)
|
||||
if err != nil {
|
||||
return cloudprovider.ACLUnknown
|
||||
}
|
||||
return cloudprovider.TBucketACLType(s3.GetCannedACL(resp.Grants))
|
||||
}
|
||||
|
||||
func (b *SBucket) GetLocation() string {
|
||||
return b.Region
|
||||
}
|
||||
|
||||
func (b *SBucket) GetIRegion() cloudprovider.ICloudRegion {
|
||||
return b.region
|
||||
}
|
||||
|
||||
func (b *SBucket) GetCreatedAt() time.Time {
|
||||
return b.CreationDate
|
||||
}
|
||||
|
||||
func (b *SBucket) GetStorageClass() string {
|
||||
return b.DataRedundancyType
|
||||
}
|
||||
|
||||
// https://docs.ksyun.com/documents/6761
|
||||
func (b *SBucket) GetAccessUrls() []cloudprovider.SBucketAccessUrl {
|
||||
ret := []cloudprovider.SBucketAccessUrl{
|
||||
{
|
||||
Url: fmt.Sprintf("%s.%s", b.Name, s3RegionEndpointMap[b.region.Region]),
|
||||
Description: "ExtranetEndpoint",
|
||||
Primary: true,
|
||||
},
|
||||
{
|
||||
Url: fmt.Sprintf("%s.%s", b.Name, strings.Replace(s3RegionEndpointMap[b.region.Region], ".ksyuncs.com", "-internal.ksyuncs.com", 1)),
|
||||
Description: "IntranetEndpoint",
|
||||
},
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (b *SBucket) GetStats() cloudprovider.SBucketStats {
|
||||
stats, err := cloudprovider.GetIBucketStats(b)
|
||||
if err != nil {
|
||||
log.Errorf("GetStats fail %s", err)
|
||||
}
|
||||
return stats
|
||||
}
|
||||
|
||||
func (region *SRegion) SetBucketAcl(bucket string, acl cloudprovider.TBucketACLType) error {
|
||||
svc := region.getS3Client()
|
||||
aclStr := string(acl)
|
||||
input := &s3.PutBucketACLInput{
|
||||
Bucket: &bucket,
|
||||
ACL: &aclStr,
|
||||
}
|
||||
_, err := svc.PutBucketACL(input)
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *SBucket) SetAcl(aclStr cloudprovider.TBucketACLType) error {
|
||||
return b.region.SetBucketAcl(b.Name, aclStr)
|
||||
}
|
||||
|
||||
func (b *SBucket) ListObjects(prefix string, marker string, delimiter string, maxCount int) (cloudprovider.SListObjectResult, error) {
|
||||
result := cloudprovider.SListObjectResult{}
|
||||
svc := b.region.getS3Client()
|
||||
input := &s3.ListObjectsInput{
|
||||
Bucket: &b.Name,
|
||||
}
|
||||
if len(prefix) > 0 {
|
||||
input.Prefix = &prefix
|
||||
}
|
||||
if len(delimiter) > 0 {
|
||||
input.Delimiter = &delimiter
|
||||
}
|
||||
if len(marker) > 0 {
|
||||
input.Marker = &marker
|
||||
}
|
||||
if maxCount > 0 {
|
||||
cnt := int64(maxCount)
|
||||
input.MaxKeys = &cnt
|
||||
}
|
||||
resp, err := svc.ListObjects(input)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
result.Objects = make([]cloudprovider.ICloudObject, 0)
|
||||
for _, object := range resp.Contents {
|
||||
ksObj := cloudprovider.SBaseCloudObject{}
|
||||
if object.StorageClass != nil {
|
||||
ksObj.StorageClass = *object.StorageClass
|
||||
}
|
||||
if object.Key != nil {
|
||||
ksObj.Key = *object.Key
|
||||
}
|
||||
if object.Size != nil {
|
||||
ksObj.SizeBytes = *object.Size
|
||||
}
|
||||
if object.ETag != nil {
|
||||
ksObj.ETag = *object.ETag
|
||||
}
|
||||
if object.LastModified != nil {
|
||||
ksObj.LastModified = *object.LastModified
|
||||
}
|
||||
|
||||
obj := &SObject{
|
||||
bucket: b,
|
||||
SBaseCloudObject: ksObj,
|
||||
}
|
||||
result.Objects = append(result.Objects, obj)
|
||||
}
|
||||
if resp.CommonPrefixes != nil {
|
||||
result.CommonPrefixes = make([]cloudprovider.ICloudObject, len(resp.CommonPrefixes))
|
||||
for i, commonPrefix := range resp.CommonPrefixes {
|
||||
result.CommonPrefixes[i] = &SObject{
|
||||
bucket: b,
|
||||
SBaseCloudObject: cloudprovider.SBaseCloudObject{Key: *commonPrefix.Prefix},
|
||||
}
|
||||
}
|
||||
}
|
||||
if resp.IsTruncated != nil {
|
||||
result.IsTruncated = *resp.IsTruncated
|
||||
}
|
||||
if resp.NextMarker != nil {
|
||||
result.NextMarker = *resp.NextMarker
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (b *SBucket) PutObject(ctx context.Context, key string, reader io.Reader, sizeBytes int64, cannedAcl cloudprovider.TBucketACLType, storageClassStr string, meta http.Header) error {
|
||||
svc := b.region.getS3Client()
|
||||
input := &s3.PutObjectInput{
|
||||
Bucket: &b.Name,
|
||||
Key: &key,
|
||||
}
|
||||
if sizeBytes > 0 {
|
||||
input.ContentLength = &sizeBytes
|
||||
}
|
||||
if meta != nil {
|
||||
input.Metadata = make(map[string]*string)
|
||||
for k, v := range meta {
|
||||
input.Metadata[k] = &v[0]
|
||||
}
|
||||
}
|
||||
if len(cannedAcl) == 0 {
|
||||
cannedAcl = b.GetAcl()
|
||||
}
|
||||
acl := string(cannedAcl)
|
||||
input.ACL = &acl
|
||||
if len(storageClassStr) > 0 {
|
||||
storageClass := string(storageClassStr)
|
||||
input.StorageClass = &storageClass
|
||||
}
|
||||
seeker, err := fileutils.NewReadSeeker(reader, sizeBytes)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "newFakeSeeker")
|
||||
}
|
||||
defer seeker.Close()
|
||||
input.Body = seeker
|
||||
_, err = svc.PutObject(input)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "PutObject")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *SBucket) NewMultipartUpload(ctx context.Context, key string, cannedAcl cloudprovider.TBucketACLType, storageClassStr string, meta http.Header) (string, error) {
|
||||
svc := b.region.getS3Client()
|
||||
input := &s3.CreateMultipartUploadInput{
|
||||
Bucket: &b.Name,
|
||||
Key: &key,
|
||||
}
|
||||
if meta != nil {
|
||||
input.Metadata = make(map[string]*string)
|
||||
for k, v := range meta {
|
||||
input.Metadata[k] = &v[0]
|
||||
}
|
||||
}
|
||||
if len(cannedAcl) == 0 {
|
||||
cannedAcl = b.GetAcl()
|
||||
}
|
||||
acl := string(cannedAcl)
|
||||
input.ACL = &acl
|
||||
if len(storageClassStr) > 0 {
|
||||
storageClass := string(storageClassStr)
|
||||
input.StorageClass = &storageClass
|
||||
}
|
||||
output, err := svc.CreateMultipartUpload(input)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "CreateMultipartUpload")
|
||||
}
|
||||
return *output.UploadID, nil
|
||||
}
|
||||
|
||||
func (b *SBucket) UploadPart(ctx context.Context, key string, uploadId string, partIndex int, reader io.Reader, partSize int64, offset, totalSize int64) (string, error) {
|
||||
svc := b.region.getS3Client()
|
||||
pn := int64(partIndex)
|
||||
input := &s3.UploadPartInput{
|
||||
Bucket: &b.Name,
|
||||
Key: &key,
|
||||
UploadID: &uploadId,
|
||||
PartNumber: &pn,
|
||||
}
|
||||
seeker, err := fileutils.NewReadSeeker(reader, partSize)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "newFakeSeeker")
|
||||
}
|
||||
defer seeker.Close()
|
||||
input.Body = seeker
|
||||
output, err := svc.UploadPart(input)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "UploadPart")
|
||||
}
|
||||
return *output.ETag, nil
|
||||
}
|
||||
|
||||
func (b *SBucket) CompleteMultipartUpload(ctx context.Context, key string, uploadId string, partEtags []string) error {
|
||||
svc := b.region.getS3Client()
|
||||
input := &s3.CompleteMultipartUploadInput{
|
||||
Bucket: &b.Name,
|
||||
Key: &key,
|
||||
UploadID: &uploadId,
|
||||
MultipartUpload: &s3.CompletedMultipartUpload{},
|
||||
}
|
||||
parts := make([]*s3.CompletedPart, len(partEtags))
|
||||
for i := range partEtags {
|
||||
pn := int64(i + 1)
|
||||
parts[i] = &s3.CompletedPart{
|
||||
PartNumber: &pn,
|
||||
ETag: &partEtags[i],
|
||||
}
|
||||
}
|
||||
input.MultipartUpload.Parts = parts
|
||||
_, err := svc.CompleteMultipartUpload(input)
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *SBucket) AbortMultipartUpload(ctx context.Context, key string, uploadId string) error {
|
||||
svc := b.region.getS3Client()
|
||||
input := &s3.AbortMultipartUploadInput{
|
||||
Bucket: &b.Name,
|
||||
Key: &key,
|
||||
UploadID: &uploadId,
|
||||
}
|
||||
_, err := svc.AbortMultipartUpload(input)
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *SBucket) DeleteObject(ctx context.Context, key string) error {
|
||||
svc := b.region.getS3Client()
|
||||
input := &s3.DeleteObjectInput{
|
||||
Bucket: &b.Name,
|
||||
Key: &key,
|
||||
}
|
||||
_, err := svc.DeleteObject(input)
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *SBucket) GetTempUrl(method string, key string, expire time.Duration) (string, error) {
|
||||
svc := b.region.getS3Client()
|
||||
input := &s3.GeneratePresignedUrlInput{
|
||||
Bucket: &b.Name,
|
||||
Key: &key,
|
||||
}
|
||||
input.HTTPMethod = s3.HTTPMethod(method)
|
||||
input.Expires = int64(expire / time.Second)
|
||||
return svc.GeneratePresignedUrl(input)
|
||||
}
|
||||
|
||||
func (b *SBucket) CopyObject(ctx context.Context, destKey string, srcBucket, srcKey string, cannedAcl cloudprovider.TBucketACLType, storageClassStr string, meta http.Header) error {
|
||||
svc := b.region.getS3Client()
|
||||
input := &s3.CopyObjectInput{
|
||||
Bucket: &b.Name,
|
||||
Key: &destKey,
|
||||
SourceBucket: &srcBucket,
|
||||
SourceKey: &srcKey,
|
||||
}
|
||||
if meta != nil {
|
||||
input.Metadata = make(map[string]*string)
|
||||
for k, v := range meta {
|
||||
input.Metadata[k] = &v[0]
|
||||
}
|
||||
}
|
||||
if cannedAcl != cloudprovider.ACLPrivate {
|
||||
acl := string(cannedAcl)
|
||||
input.ACL = &acl
|
||||
}
|
||||
if storageClassStr != "" {
|
||||
storageClass := string(storageClassStr)
|
||||
input.StorageClass = &storageClass
|
||||
}
|
||||
_, err := svc.CopyObject(input)
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *SBucket) GetObject(ctx context.Context, key string, rangeOpt *cloudprovider.SGetObjectRange) (io.ReadCloser, error) {
|
||||
svc := b.region.getS3Client()
|
||||
input := &s3.GetObjectInput{
|
||||
Bucket: &b.Name,
|
||||
Key: &key,
|
||||
}
|
||||
if rangeOpt != nil {
|
||||
rangeInput := rangeOpt.String()
|
||||
input.Range = &rangeInput
|
||||
}
|
||||
output, err := svc.GetObject(input)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetObject")
|
||||
}
|
||||
return output.Body, nil
|
||||
}
|
||||
|
||||
func (b *SBucket) CopyPart(ctx context.Context, key string, uploadId string, partNumber int, srcBucket string, srcKey string, srcOffset int64, srcLength int64) (string, error) {
|
||||
svc := b.region.getS3Client()
|
||||
pn := int64(partNumber)
|
||||
copySourceRange := fmt.Sprintf("bytes=%d-%d", srcOffset, srcOffset+srcLength-1)
|
||||
input := &s3.UploadPartCopyInput{
|
||||
Bucket: &b.Name,
|
||||
Key: &key,
|
||||
UploadID: &uploadId,
|
||||
PartNumber: &pn,
|
||||
SourceBucket: &srcBucket,
|
||||
SourceKey: &srcKey,
|
||||
CopySourceRange: ©SourceRange,
|
||||
}
|
||||
output, err := svc.UploadPartCopy(input)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "UploadPartCopy")
|
||||
}
|
||||
return *output.CopyPartResult.ETag, nil
|
||||
|
||||
}
|
||||
|
||||
func (b *SBucket) GetTags() (map[string]string, error) {
|
||||
svc := b.region.getS3Client()
|
||||
input := &s3.GetBucketTaggingInput{
|
||||
Bucket: &b.Name,
|
||||
}
|
||||
output, err := svc.GetBucketTagging(input)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetBucketTagging")
|
||||
}
|
||||
result := map[string]string{}
|
||||
if output.Tagging == nil {
|
||||
return nil, nil
|
||||
}
|
||||
for _, tag := range output.Tagging.TagSet {
|
||||
result[*tag.Key] = *tag.Value
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (b *SBucket) SetTags(tags map[string]string, replace bool) error {
|
||||
svc := b.region.getS3Client()
|
||||
input := &s3.PutBucketTaggingInput{
|
||||
Bucket: &b.Name,
|
||||
}
|
||||
if replace {
|
||||
input.Tagging = &s3.Tagging{
|
||||
TagSet: make([]*s3.Tag, 0),
|
||||
}
|
||||
}
|
||||
for k, v := range tags {
|
||||
input.Tagging.TagSet = append(input.Tagging.TagSet, &s3.Tag{Key: &k, Value: &v})
|
||||
}
|
||||
_, err := svc.PutBucketTagging(input)
|
||||
log.Infof("put tagging %s error: %v", jsonutils.Marshal(input).String(), err)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "PutBucketTagging(%s)", b.Name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *SBucket) ListMultipartUploads() ([]cloudprovider.SBucketMultipartUploads, error) {
|
||||
result := []cloudprovider.SBucketMultipartUploads{}
|
||||
svc := b.region.getS3Client()
|
||||
keyMarker := ""
|
||||
uploadIDMarker := ""
|
||||
for {
|
||||
input := &s3.ListMultipartUploadsInput{
|
||||
Bucket: &b.Name,
|
||||
KeyMarker: &keyMarker,
|
||||
UploadIDMarker: &uploadIDMarker,
|
||||
}
|
||||
output, err := svc.ListMultipartUploads(input)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "ListMultipartUploads")
|
||||
}
|
||||
for _, upload := range output.Uploads {
|
||||
result = append(result, cloudprovider.SBucketMultipartUploads{
|
||||
ObjectName: *upload.Key,
|
||||
UploadID: *upload.UploadID,
|
||||
Initiated: *upload.Initiated,
|
||||
})
|
||||
}
|
||||
keyMarker = *output.NextKeyMarker
|
||||
uploadIDMarker = *output.NextUploadIDMarker
|
||||
if output.IsTruncated == nil || !*output.IsTruncated {
|
||||
break
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (region *SRegion) GetIBuckets() ([]cloudprovider.ICloudBucket, error) {
|
||||
buckets, err := region.client.GetBuckets()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := make([]cloudprovider.ICloudBucket, 0)
|
||||
for i := range buckets {
|
||||
buckets[i].region = region
|
||||
if strings.EqualFold(buckets[i].Region, s3RegionMap[region.Region]) {
|
||||
ret = append(ret, &buckets[i])
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (region *SRegion) getS3Client() *s3.S3 {
|
||||
return region.client.getS3Client(region.Region)
|
||||
}
|
||||
|
||||
// https://docs.ksyun.com/documents/6761?type=3
|
||||
var s3RegionMap = map[string]string{
|
||||
"": "BEIJING",
|
||||
"ap-singapore-1": "SINGAPORE",
|
||||
"cn-beijing-6": "BEIJING",
|
||||
"cn-guangzhou-1": "GUANGZHOU",
|
||||
"cn-shanghai-2": "SHANGHAI",
|
||||
"cn-northwest-1": "QINGYANG",
|
||||
}
|
||||
var s3RegionEndpointMap = map[string]string{
|
||||
"": "ks3-cn-beijing.ksyuncs.com",
|
||||
"ap-singapore-1": "ks3-sgp.ksyuncs.com",
|
||||
"cn-beijing-6": "ks3-cn-beijing.ksyuncs.com",
|
||||
"cn-guangzhou-1": "ks3-cn-guangzhou.ksyuncs.com",
|
||||
"cn-shanghai-2": "ks3-cn-shanghai.ksyuncs.com",
|
||||
"cn-northwest-1": "ks3-cn-qingyang.ksyuncs.com",
|
||||
}
|
||||
|
||||
func (cli *SKsyunClient) getS3Client(regionId string) *s3.S3 {
|
||||
aksk := credentials.NewStaticCredentials(cli.accessKeyId, cli.accessKeySecret, "")
|
||||
cfg := aws.Config{
|
||||
Region: s3RegionMap[regionId],
|
||||
Credentials: aksk,
|
||||
Endpoint: s3RegionEndpointMap[regionId],
|
||||
HTTPClient: cli.getDefaultClient(),
|
||||
SignerVersion: "V4_UNSIGNED_PAYLOAD_SIGNER",
|
||||
MaxRetries: 1,
|
||||
}
|
||||
if cli.debug {
|
||||
cfg.LogLevel = aws.Debug
|
||||
}
|
||||
return s3.New(&cfg)
|
||||
}
|
||||
|
||||
func (cli *SKsyunClient) GetBuckets() ([]SBucket, error) {
|
||||
svc := cli.getS3Client("")
|
||||
input := &s3.ListBucketsInput{}
|
||||
resp, err := svc.ListBuckets(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := make([]SBucket, 0)
|
||||
for _, b := range resp.Buckets {
|
||||
ret = append(ret, SBucket{
|
||||
Name: *b.Name,
|
||||
Region: *b.Region,
|
||||
Type: *b.Type,
|
||||
VisitType: *b.VisitType,
|
||||
DataRedundancyType: *b.DataRedundancyType,
|
||||
CreationDate: *b.CreationDate,
|
||||
})
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (region *SRegion) CreateIBucket(name string, storageClassStr string, aclStr string) error {
|
||||
svc := region.getS3Client()
|
||||
input := &s3.CreateBucketInput{
|
||||
Bucket: &name,
|
||||
}
|
||||
if aclStr != "" {
|
||||
acl := string(aclStr)
|
||||
input.ACL = &acl
|
||||
}
|
||||
_, err := svc.CreateBucket(input)
|
||||
return err
|
||||
}
|
||||
|
||||
func (region *SRegion) GetIBucketById(name string) (cloudprovider.ICloudBucket, error) {
|
||||
buckets, err := region.GetIBuckets()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "region.GetBuckets")
|
||||
}
|
||||
for _, b := range buckets {
|
||||
if b.GetName() == name {
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.Wrap(cloudprovider.ErrNotFound, "Bucket Not Found")
|
||||
}
|
||||
|
||||
func (region *SRegion) GetIBucketByName(name string) (cloudprovider.ICloudBucket, error) {
|
||||
return region.GetIBucketById(name)
|
||||
}
|
||||
|
||||
func (region *SRegion) DeleteIBucket(name string) error {
|
||||
svc := region.getS3Client()
|
||||
input := &s3.DeleteBucketInput{
|
||||
Bucket: &name,
|
||||
}
|
||||
_, err := svc.DeleteBucket(input)
|
||||
return err
|
||||
}
|
||||
|
||||
func (region *SRegion) IBucketExist(name string) (bool, error) {
|
||||
svc := region.getS3Client()
|
||||
input := &s3.HeadBucketInput{
|
||||
Bucket: &name,
|
||||
}
|
||||
_, err := svc.HeadBucket(input)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
5
vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/ksyun.go
generated
vendored
5
vendor/yunion.io/x/cloudmux/pkg/multicloud/ksyun/ksyun.go
generated
vendored
@@ -157,6 +157,10 @@ func (cli *SKsyunClient) getDefaultClient() *http.Client {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
// ks3
|
||||
if len(action) == 0 && strings.Contains(req.URL.String(), "ks3-") {
|
||||
return nil, nil
|
||||
}
|
||||
if cli.cpcfg.ReadOnly {
|
||||
return nil, errors.Wrapf(cloudprovider.ErrAccountReadOnly, "%s %s", req.Method, req.URL.Path)
|
||||
}
|
||||
@@ -353,6 +357,7 @@ func (cli *SKsyunClient) GetCapabilities() []string {
|
||||
cloudprovider.CLOUD_CAPABILITY_COMPUTE + cloudprovider.READ_ONLY_SUFFIX,
|
||||
cloudprovider.CLOUD_CAPABILITY_PROJECT + cloudprovider.READ_ONLY_SUFFIX,
|
||||
cloudprovider.CLOUD_CAPABILITY_CLOUDID,
|
||||
cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE,
|
||||
cloudprovider.CLOUD_CAPABILITY_RDS + cloudprovider.READ_ONLY_SUFFIX,
|
||||
}
|
||||
return caps
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user