mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-05-07 22:20:24 +00:00
Update Go AWS SDK to the latest version
This commit is contained in:
committed by
Andrey Smirnov
parent
d08be990ef
commit
94a72b23ff
+2
-1
@@ -21,7 +21,8 @@ func Build(r *request.Request) {
|
||||
"Version": {r.ClientInfo.APIVersion},
|
||||
}
|
||||
if err := queryutil.Parse(body, r.Params, true); err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed encoding EC2 Query request", err)
|
||||
r.Error = awserr.New(request.ErrCodeSerialization,
|
||||
"failed encoding EC2 Query request", err)
|
||||
}
|
||||
|
||||
if !r.IsPresigned() {
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ func BenchmarkEC2QueryBuild_Complex_ec2AuthorizeSecurityGroupEgress(b *testing.B
|
||||
IpProtocol: aws.String("String"),
|
||||
SourceSecurityGroupName: aws.String("String"),
|
||||
SourceSecurityGroupOwnerId: aws.String("String"),
|
||||
ToPort: aws.Int64(1),
|
||||
ToPort: aws.Int64(1),
|
||||
}
|
||||
|
||||
benchEC2QueryBuild(b, "AuthorizeSecurityGroupEgress", params)
|
||||
|
||||
+432
-71
@@ -75,7 +75,8 @@ func newInputService1ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice1protocoltest",
|
||||
ServiceName: "InputService1ProtocolTest",
|
||||
ServiceID: "InputService1ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -108,7 +109,7 @@ const opInputService1TestCaseOperation1 = "OperationName"
|
||||
// InputService1TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService1TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -139,8 +140,7 @@ func (c *InputService1ProtocolTest) InputService1TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService1TestShapeInputService1TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -228,7 +228,8 @@ func newInputService2ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice2protocoltest",
|
||||
ServiceName: "InputService2ProtocolTest",
|
||||
ServiceID: "InputService2ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -261,7 +262,7 @@ const opInputService2TestCaseOperation1 = "OperationName"
|
||||
// InputService2TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService2TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -292,8 +293,7 @@ func (c *InputService2ProtocolTest) InputService2TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService2TestShapeInputService2TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -389,7 +389,8 @@ func newInputService3ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice3protocoltest",
|
||||
ServiceName: "InputService3ProtocolTest",
|
||||
ServiceID: "InputService3ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -422,7 +423,7 @@ const opInputService3TestCaseOperation1 = "OperationName"
|
||||
// InputService3TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService3TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -453,8 +454,7 @@ func (c *InputService3ProtocolTest) InputService3TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService3TestShapeInputService3TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -546,7 +546,8 @@ func newInputService4ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice4protocoltest",
|
||||
ServiceName: "InputService4ProtocolTest",
|
||||
ServiceID: "InputService4ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -579,7 +580,7 @@ const opInputService4TestCaseOperation1 = "OperationName"
|
||||
// InputService4TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService4TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -610,8 +611,7 @@ func (c *InputService4ProtocolTest) InputService4TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService4TestShapeInputService4TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -715,7 +715,8 @@ func newInputService5ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice5protocoltest",
|
||||
ServiceName: "InputService5ProtocolTest",
|
||||
ServiceID: "InputService5ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -748,7 +749,7 @@ const opInputService5TestCaseOperation1 = "OperationName"
|
||||
// InputService5TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService5TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -779,8 +780,7 @@ func (c *InputService5ProtocolTest) InputService5TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService5TestShapeInputService5TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -860,7 +860,8 @@ func newInputService6ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice6protocoltest",
|
||||
ServiceName: "InputService6ProtocolTest",
|
||||
ServiceID: "InputService6ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -893,7 +894,7 @@ const opInputService6TestCaseOperation1 = "OperationName"
|
||||
// InputService6TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService6TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -924,8 +925,7 @@ func (c *InputService6ProtocolTest) InputService6TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService6TestShapeInputService6TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1005,7 +1005,8 @@ func newInputService7ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice7protocoltest",
|
||||
ServiceName: "InputService7ProtocolTest",
|
||||
ServiceID: "InputService7ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1038,7 +1039,7 @@ const opInputService7TestCaseOperation1 = "OperationName"
|
||||
// InputService7TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService7TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1069,8 +1070,7 @@ func (c *InputService7ProtocolTest) InputService7TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService7TestShapeInputService7TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1151,7 +1151,8 @@ func newInputService8ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice8protocoltest",
|
||||
ServiceName: "InputService8ProtocolTest",
|
||||
ServiceID: "InputService8ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1184,7 +1185,7 @@ const opInputService8TestCaseOperation1 = "OperationName"
|
||||
// InputService8TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService8TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1215,8 +1216,7 @@ func (c *InputService8ProtocolTest) InputService8TestCaseOperation1Request(input
|
||||
|
||||
output = &InputService8TestShapeInputService8TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1252,7 +1252,11 @@ func (c *InputService8ProtocolTest) InputService8TestCaseOperation1WithContext(c
|
||||
type InputService8TestShapeInputService8TestCaseOperation1Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
TimeArg *time.Time `type:"timestamp" timestampFormat:"iso8601"`
|
||||
TimeArg *time.Time `type:"timestamp"`
|
||||
|
||||
TimeCustom *time.Time `type:"timestamp" timestampFormat:"unixTimestamp"`
|
||||
|
||||
TimeFormat *time.Time `type:"timestamp" timestampFormat:"unixTimestamp"`
|
||||
}
|
||||
|
||||
// SetTimeArg sets the TimeArg field's value.
|
||||
@@ -1261,6 +1265,18 @@ func (s *InputService8TestShapeInputService8TestCaseOperation1Input) SetTimeArg(
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeCustom sets the TimeCustom field's value.
|
||||
func (s *InputService8TestShapeInputService8TestCaseOperation1Input) SetTimeCustom(v time.Time) *InputService8TestShapeInputService8TestCaseOperation1Input {
|
||||
s.TimeCustom = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeFormat sets the TimeFormat field's value.
|
||||
func (s *InputService8TestShapeInputService8TestCaseOperation1Input) SetTimeFormat(v time.Time) *InputService8TestShapeInputService8TestCaseOperation1Input {
|
||||
s.TimeFormat = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type InputService8TestShapeInputService8TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
@@ -1296,7 +1312,8 @@ func newInputService9ProtocolTestClient(cfg aws.Config, handlers request.Handler
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice9protocoltest",
|
||||
ServiceName: "InputService9ProtocolTest",
|
||||
ServiceID: "InputService9ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1329,7 +1346,7 @@ const opInputService9TestCaseOperation1 = "OperationName"
|
||||
// InputService9TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService9TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1348,20 +1365,19 @@ const opInputService9TestCaseOperation1 = "OperationName"
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *InputService9ProtocolTest) InputService9TestCaseOperation1Request(input *InputService9TestShapeInputService9TestCaseOperation2Input) (req *request.Request, output *InputService9TestShapeInputService9TestCaseOperation1Output) {
|
||||
func (c *InputService9ProtocolTest) InputService9TestCaseOperation1Request(input *InputService9TestShapeInputService9TestCaseOperation1Input) (req *request.Request, output *InputService9TestShapeInputService9TestCaseOperation1Output) {
|
||||
op := &request.Operation{
|
||||
Name: opInputService9TestCaseOperation1,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService9TestShapeInputService9TestCaseOperation2Input{}
|
||||
input = &InputService9TestShapeInputService9TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
output = &InputService9TestShapeInputService9TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1373,7 +1389,7 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation1Request(input
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation InputService9TestCaseOperation1 for usage and error information.
|
||||
func (c *InputService9ProtocolTest) InputService9TestCaseOperation1(input *InputService9TestShapeInputService9TestCaseOperation2Input) (*InputService9TestShapeInputService9TestCaseOperation1Output, error) {
|
||||
func (c *InputService9ProtocolTest) InputService9TestCaseOperation1(input *InputService9TestShapeInputService9TestCaseOperation1Input) (*InputService9TestShapeInputService9TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService9TestCaseOperation1Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
@@ -1387,7 +1403,7 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation1(input *Input
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *InputService9ProtocolTest) InputService9TestCaseOperation1WithContext(ctx aws.Context, input *InputService9TestShapeInputService9TestCaseOperation2Input, opts ...request.Option) (*InputService9TestShapeInputService9TestCaseOperation1Output, error) {
|
||||
func (c *InputService9ProtocolTest) InputService9TestCaseOperation1WithContext(ctx aws.Context, input *InputService9TestShapeInputService9TestCaseOperation1Input, opts ...request.Option) (*InputService9TestShapeInputService9TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService9TestCaseOperation1Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
@@ -1399,7 +1415,7 @@ const opInputService9TestCaseOperation2 = "OperationName"
|
||||
// InputService9TestCaseOperation2Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService9TestCaseOperation2 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1430,8 +1446,7 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation2Request(input
|
||||
|
||||
output = &InputService9TestShapeInputService9TestCaseOperation2Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1464,6 +1479,18 @@ func (c *InputService9ProtocolTest) InputService9TestCaseOperation2WithContext(c
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type InputService9TestShapeInputService9TestCaseOperation1Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
Token *string `type:"string" idempotencyToken:"true"`
|
||||
}
|
||||
|
||||
// SetToken sets the Token field's value.
|
||||
func (s *InputService9TestShapeInputService9TestCaseOperation1Input) SetToken(v string) *InputService9TestShapeInputService9TestCaseOperation1Input {
|
||||
s.Token = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type InputService9TestShapeInputService9TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
@@ -1515,7 +1542,8 @@ func newInputService10ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "inputservice10protocoltest",
|
||||
ServiceName: "InputService10ProtocolTest",
|
||||
ServiceID: "InputService10ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1548,7 +1576,7 @@ const opInputService10TestCaseOperation1 = "OperationName"
|
||||
// InputService10TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService10TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1567,20 +1595,19 @@ const opInputService10TestCaseOperation1 = "OperationName"
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *InputService10ProtocolTest) InputService10TestCaseOperation1Request(input *InputService10TestShapeInputService10TestCaseOperation2Input) (req *request.Request, output *InputService10TestShapeInputService10TestCaseOperation1Output) {
|
||||
func (c *InputService10ProtocolTest) InputService10TestCaseOperation1Request(input *InputService10TestShapeInputService10TestCaseOperation1Input) (req *request.Request, output *InputService10TestShapeInputService10TestCaseOperation1Output) {
|
||||
op := &request.Operation{
|
||||
Name: opInputService10TestCaseOperation1,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService10TestShapeInputService10TestCaseOperation2Input{}
|
||||
input = &InputService10TestShapeInputService10TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
output = &InputService10TestShapeInputService10TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1592,7 +1619,7 @@ func (c *InputService10ProtocolTest) InputService10TestCaseOperation1Request(inp
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation InputService10TestCaseOperation1 for usage and error information.
|
||||
func (c *InputService10ProtocolTest) InputService10TestCaseOperation1(input *InputService10TestShapeInputService10TestCaseOperation2Input) (*InputService10TestShapeInputService10TestCaseOperation1Output, error) {
|
||||
func (c *InputService10ProtocolTest) InputService10TestCaseOperation1(input *InputService10TestShapeInputService10TestCaseOperation1Input) (*InputService10TestShapeInputService10TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService10TestCaseOperation1Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
@@ -1606,7 +1633,7 @@ func (c *InputService10ProtocolTest) InputService10TestCaseOperation1(input *Inp
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *InputService10ProtocolTest) InputService10TestCaseOperation1WithContext(ctx aws.Context, input *InputService10TestShapeInputService10TestCaseOperation2Input, opts ...request.Option) (*InputService10TestShapeInputService10TestCaseOperation1Output, error) {
|
||||
func (c *InputService10ProtocolTest) InputService10TestCaseOperation1WithContext(ctx aws.Context, input *InputService10TestShapeInputService10TestCaseOperation1Input, opts ...request.Option) (*InputService10TestShapeInputService10TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService10TestCaseOperation1Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
@@ -1618,7 +1645,7 @@ const opInputService10TestCaseOperation2 = "OperationName"
|
||||
// InputService10TestCaseOperation2Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService10TestCaseOperation2 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1649,8 +1676,7 @@ func (c *InputService10ProtocolTest) InputService10TestCaseOperation2Request(inp
|
||||
|
||||
output = &InputService10TestShapeInputService10TestCaseOperation2Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Remove(ec2query.UnmarshalHandler)
|
||||
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1683,6 +1709,26 @@ func (c *InputService10ProtocolTest) InputService10TestCaseOperation2WithContext
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type InputService10TestShapeInputService10TestCaseOperation1Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
FooEnum *string `type:"string" enum:"InputService10TestShapeEnumType"`
|
||||
|
||||
ListEnums []*string `type:"list"`
|
||||
}
|
||||
|
||||
// SetFooEnum sets the FooEnum field's value.
|
||||
func (s *InputService10TestShapeInputService10TestCaseOperation1Input) SetFooEnum(v string) *InputService10TestShapeInputService10TestCaseOperation1Input {
|
||||
s.FooEnum = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetListEnums sets the ListEnums field's value.
|
||||
func (s *InputService10TestShapeInputService10TestCaseOperation1Input) SetListEnums(v []*string) *InputService10TestShapeInputService10TestCaseOperation1Input {
|
||||
s.ListEnums = v
|
||||
return s
|
||||
}
|
||||
|
||||
type InputService10TestShapeInputService10TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
@@ -1719,6 +1765,263 @@ const (
|
||||
EnumTypeBar = "bar"
|
||||
)
|
||||
|
||||
// InputService11ProtocolTest provides the API operation methods for making requests to
|
||||
// . See this package's package overview docs
|
||||
// for details on the service.
|
||||
//
|
||||
// InputService11ProtocolTest methods are safe to use concurrently. It is not safe to
|
||||
// modify mutate any of the struct's properties though.
|
||||
type InputService11ProtocolTest struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// New creates a new instance of the InputService11ProtocolTest client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
// // Create a InputService11ProtocolTest client from just a session.
|
||||
// svc := inputservice11protocoltest.New(mySession)
|
||||
//
|
||||
// // Create a InputService11ProtocolTest client with additional configuration
|
||||
// svc := inputservice11protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func NewInputService11ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *InputService11ProtocolTest {
|
||||
c := p.ClientConfig("inputservice11protocoltest", cfgs...)
|
||||
return newInputService11ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newInputService11ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *InputService11ProtocolTest {
|
||||
svc := &InputService11ProtocolTest{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "InputService11ProtocolTest",
|
||||
ServiceID: "InputService11ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "2014-01-01",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(ec2query.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(ec2query.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(ec2query.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(ec2query.UnmarshalErrorHandler)
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a InputService11ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *InputService11ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opInputService11TestCaseOperation1 = "StaticOp"
|
||||
|
||||
// InputService11TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService11TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See InputService11TestCaseOperation1 for more information on using the InputService11TestCaseOperation1
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the InputService11TestCaseOperation1Request method.
|
||||
// req, resp := client.InputService11TestCaseOperation1Request(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *InputService11ProtocolTest) InputService11TestCaseOperation1Request(input *InputService11TestShapeInputService11TestCaseOperation1Input) (req *request.Request, output *InputService11TestShapeInputService11TestCaseOperation1Output) {
|
||||
op := &request.Operation{
|
||||
Name: opInputService11TestCaseOperation1,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService11TestShapeInputService11TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
output = &InputService11TestShapeInputService11TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Build.PushBackNamed(protocol.NewHostPrefixHandler("data-", nil))
|
||||
req.Handlers.Build.PushBackNamed(protocol.ValidateEndpointHostHandler)
|
||||
return
|
||||
}
|
||||
|
||||
// InputService11TestCaseOperation1 API operation for .
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation InputService11TestCaseOperation1 for usage and error information.
|
||||
func (c *InputService11ProtocolTest) InputService11TestCaseOperation1(input *InputService11TestShapeInputService11TestCaseOperation1Input) (*InputService11TestShapeInputService11TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService11TestCaseOperation1Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// InputService11TestCaseOperation1WithContext is the same as InputService11TestCaseOperation1 with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See InputService11TestCaseOperation1 for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *InputService11ProtocolTest) InputService11TestCaseOperation1WithContext(ctx aws.Context, input *InputService11TestShapeInputService11TestCaseOperation1Input, opts ...request.Option) (*InputService11TestShapeInputService11TestCaseOperation1Output, error) {
|
||||
req, out := c.InputService11TestCaseOperation1Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
const opInputService11TestCaseOperation2 = "MemberRefOp"
|
||||
|
||||
// InputService11TestCaseOperation2Request generates a "aws/request.Request" representing the
|
||||
// client's request for the InputService11TestCaseOperation2 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See InputService11TestCaseOperation2 for more information on using the InputService11TestCaseOperation2
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the InputService11TestCaseOperation2Request method.
|
||||
// req, resp := client.InputService11TestCaseOperation2Request(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *InputService11ProtocolTest) InputService11TestCaseOperation2Request(input *InputService11TestShapeInputService11TestCaseOperation2Input) (req *request.Request, output *InputService11TestShapeInputService11TestCaseOperation2Output) {
|
||||
op := &request.Operation{
|
||||
Name: opInputService11TestCaseOperation2,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &InputService11TestShapeInputService11TestCaseOperation2Input{}
|
||||
}
|
||||
|
||||
output = &InputService11TestShapeInputService11TestCaseOperation2Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Swap(ec2query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
req.Handlers.Build.PushBackNamed(protocol.NewHostPrefixHandler("foo-{Name}.", input.hostLabels))
|
||||
req.Handlers.Build.PushBackNamed(protocol.ValidateEndpointHostHandler)
|
||||
return
|
||||
}
|
||||
|
||||
// InputService11TestCaseOperation2 API operation for .
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation InputService11TestCaseOperation2 for usage and error information.
|
||||
func (c *InputService11ProtocolTest) InputService11TestCaseOperation2(input *InputService11TestShapeInputService11TestCaseOperation2Input) (*InputService11TestShapeInputService11TestCaseOperation2Output, error) {
|
||||
req, out := c.InputService11TestCaseOperation2Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// InputService11TestCaseOperation2WithContext is the same as InputService11TestCaseOperation2 with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See InputService11TestCaseOperation2 for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *InputService11ProtocolTest) InputService11TestCaseOperation2WithContext(ctx aws.Context, input *InputService11TestShapeInputService11TestCaseOperation2Input, opts ...request.Option) (*InputService11TestShapeInputService11TestCaseOperation2Output, error) {
|
||||
req, out := c.InputService11TestCaseOperation2Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type InputService11TestShapeInputService11TestCaseOperation1Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
Name *string `type:"string"`
|
||||
}
|
||||
|
||||
// SetName sets the Name field's value.
|
||||
func (s *InputService11TestShapeInputService11TestCaseOperation1Input) SetName(v string) *InputService11TestShapeInputService11TestCaseOperation1Input {
|
||||
s.Name = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type InputService11TestShapeInputService11TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
type InputService11TestShapeInputService11TestCaseOperation2Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
// Name is a required field
|
||||
Name *string `type:"string" required:"true"`
|
||||
}
|
||||
|
||||
// Validate inspects the fields of the type to determine if they are valid.
|
||||
func (s *InputService11TestShapeInputService11TestCaseOperation2Input) Validate() error {
|
||||
invalidParams := request.ErrInvalidParams{Context: "InputService11TestShapeInputService11TestCaseOperation2Input"}
|
||||
if s.Name == nil {
|
||||
invalidParams.Add(request.NewErrParamRequired("Name"))
|
||||
}
|
||||
if s.Name != nil && len(*s.Name) < 1 {
|
||||
invalidParams.Add(request.NewErrParamMinLen("Name", 1))
|
||||
}
|
||||
|
||||
if invalidParams.Len() > 0 {
|
||||
return invalidParams
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetName sets the Name field's value.
|
||||
func (s *InputService11TestShapeInputService11TestCaseOperation2Input) SetName(v string) *InputService11TestShapeInputService11TestCaseOperation2Input {
|
||||
s.Name = &v
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *InputService11TestShapeInputService11TestCaseOperation2Input) hostLabels() map[string]string {
|
||||
return map[string]string{
|
||||
"Name": aws.StringValue(s.Name),
|
||||
}
|
||||
}
|
||||
|
||||
type InputService11TestShapeInputService11TestCaseOperation2Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
//
|
||||
// Tests begin here
|
||||
//
|
||||
@@ -1733,7 +2036,7 @@ func TestInputService1ProtocolTestScalarMembersCase1(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1763,7 +2066,7 @@ func TestInputService2ProtocolTestStructureWithLocationNameAndQueryNameAppliedTo
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1793,7 +2096,7 @@ func TestInputService3ProtocolTestNestedStructureMembersCase1(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1840,7 +2143,7 @@ func TestInputService4ProtocolTestListTypesCase1(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1872,7 +2175,7 @@ func TestInputService5ProtocolTestListWithLocationNameAppliedToMemberCase1(t *te
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1904,7 +2207,7 @@ func TestInputService6ProtocolTestListWithLocationNameAndQueryNameCase1(t *testi
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1932,7 +2235,7 @@ func TestInputService7ProtocolTestBase64EncodedBlobsCase1(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1954,13 +2257,15 @@ func TestInputService7ProtocolTestBase64EncodedBlobsCase1(t *testing.T) {
|
||||
func TestInputService8ProtocolTestTimestampValuesCase1(t *testing.T) {
|
||||
svc := NewInputService8ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
input := &InputService8TestShapeInputService8TestCaseOperation1Input{
|
||||
TimeArg: aws.Time(time.Unix(1422172800, 0)),
|
||||
TimeArg: aws.Time(time.Unix(1422172800, 0)),
|
||||
TimeCustom: aws.Time(time.Unix(1422172800, 0)),
|
||||
TimeFormat: aws.Time(time.Unix(1422172800, 0)),
|
||||
}
|
||||
req, _ := svc.InputService8TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -1970,7 +2275,7 @@ func TestInputService8ProtocolTestTimestampValuesCase1(t *testing.T) {
|
||||
t.Errorf("expect body not to be nil")
|
||||
}
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
awstesting.AssertQuery(t, `Action=OperationName&TimeArg=2015-01-25T08%3A00%3A00Z&Version=2014-01-01`, util.Trim(string(body)))
|
||||
awstesting.AssertQuery(t, `Action=OperationName&TimeArg=2015-01-25T08%3A00%3A00Z&TimeCustom=1422172800&TimeFormat=1422172800&Version=2014-01-01`, util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
awstesting.AssertURL(t, "https://test/", r.URL.String())
|
||||
@@ -1981,14 +2286,14 @@ func TestInputService8ProtocolTestTimestampValuesCase1(t *testing.T) {
|
||||
|
||||
func TestInputService9ProtocolTestIdempotencyTokenAutoFillCase1(t *testing.T) {
|
||||
svc := NewInputService9ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
input := &InputService9TestShapeInputService9TestCaseOperation2Input{
|
||||
input := &InputService9TestShapeInputService9TestCaseOperation1Input{
|
||||
Token: aws.String("abc123"),
|
||||
}
|
||||
req, _ := svc.InputService9TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -2014,7 +2319,7 @@ func TestInputService9ProtocolTestIdempotencyTokenAutoFillCase2(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -2035,7 +2340,7 @@ func TestInputService9ProtocolTestIdempotencyTokenAutoFillCase2(t *testing.T) {
|
||||
|
||||
func TestInputService10ProtocolTestEnumCase1(t *testing.T) {
|
||||
svc := NewInputService10ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
input := &InputService10TestShapeInputService10TestCaseOperation2Input{
|
||||
input := &InputService10TestShapeInputService10TestCaseOperation1Input{
|
||||
ListEnums: []*string{
|
||||
aws.String("foo"),
|
||||
aws.String(""),
|
||||
@@ -2046,7 +2351,7 @@ func TestInputService10ProtocolTestEnumCase1(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -2072,7 +2377,7 @@ func TestInputService10ProtocolTestEnumCase2(t *testing.T) {
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
ec2query.Build(req)
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
@@ -2090,3 +2395,59 @@ func TestInputService10ProtocolTestEnumCase2(t *testing.T) {
|
||||
// assert headers
|
||||
|
||||
}
|
||||
|
||||
func TestInputService11ProtocolTestEndpointHostTraitCase1(t *testing.T) {
|
||||
svc := NewInputService11ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://service.region.amazonaws.com")})
|
||||
input := &InputService11TestShapeInputService11TestCaseOperation1Input{
|
||||
Name: aws.String("myname"),
|
||||
}
|
||||
req, _ := svc.InputService11TestCaseOperation1Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
|
||||
// assert body
|
||||
if r.Body == nil {
|
||||
t.Errorf("expect body not to be nil")
|
||||
}
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
awstesting.AssertQuery(t, `Action=StaticOp&Name=myname&Version=2014-01-01`, util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
awstesting.AssertURL(t, "https://data-service.region.amazonaws.com/", r.URL.String())
|
||||
|
||||
// assert headers
|
||||
|
||||
}
|
||||
|
||||
func TestInputService11ProtocolTestEndpointHostTraitCase2(t *testing.T) {
|
||||
svc := NewInputService11ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://service.region.amazonaws.com")})
|
||||
input := &InputService11TestShapeInputService11TestCaseOperation2Input{
|
||||
Name: aws.String("myname"),
|
||||
}
|
||||
req, _ := svc.InputService11TestCaseOperation2Request(input)
|
||||
r := req.HTTPRequest
|
||||
|
||||
// build request
|
||||
req.Build()
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect no error, got %v", req.Error)
|
||||
}
|
||||
|
||||
// assert body
|
||||
if r.Body == nil {
|
||||
t.Errorf("expect body not to be nil")
|
||||
}
|
||||
body, _ := ioutil.ReadAll(r.Body)
|
||||
awstesting.AssertQuery(t, `Action=MemberRefOp&Name=myname&Version=2014-01-01`, util.Trim(string(body)))
|
||||
|
||||
// assert URL
|
||||
awstesting.AssertURL(t, "https://foo-myname.service.region.amazonaws.com/", r.URL.String())
|
||||
|
||||
// assert headers
|
||||
|
||||
}
|
||||
|
||||
+24
-10
@@ -4,7 +4,6 @@ package ec2query
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"io"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
@@ -27,7 +26,12 @@ func Unmarshal(r *request.Request) {
|
||||
decoder := xml.NewDecoder(r.HTTPResponse.Body)
|
||||
err := xmlutil.UnmarshalXML(r.Data, decoder, "")
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed decoding EC2 Query response", err)
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed decoding EC2 Query response", err),
|
||||
r.HTTPResponse.StatusCode,
|
||||
r.RequestID,
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -35,7 +39,11 @@ func Unmarshal(r *request.Request) {
|
||||
|
||||
// UnmarshalMeta unmarshals response headers for the EC2 protocol.
|
||||
func UnmarshalMeta(r *request.Request) {
|
||||
// TODO implement unmarshaling of request IDs
|
||||
r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid")
|
||||
if r.RequestID == "" {
|
||||
// Alternative version of request id in the header
|
||||
r.RequestID = r.HTTPResponse.Header.Get("X-Amz-Request-Id")
|
||||
}
|
||||
}
|
||||
|
||||
type xmlErrorResponse struct {
|
||||
@@ -49,15 +57,21 @@ type xmlErrorResponse struct {
|
||||
func UnmarshalError(r *request.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
|
||||
resp := &xmlErrorResponse{}
|
||||
err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp)
|
||||
if err != nil && err != io.EOF {
|
||||
r.Error = awserr.New("SerializationError", "failed decoding EC2 Query error response", err)
|
||||
} else {
|
||||
var respErr xmlErrorResponse
|
||||
err := xmlutil.UnmarshalXMLError(&respErr, r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(resp.Code, resp.Message, nil),
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed to unmarshal error message", err),
|
||||
r.HTTPResponse.StatusCode,
|
||||
resp.RequestID,
|
||||
r.RequestID,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(respErr.Code, respErr.Message, nil),
|
||||
r.HTTPResponse.StatusCode,
|
||||
respErr.RequestID,
|
||||
)
|
||||
}
|
||||
|
||||
Generated
Vendored
+82
@@ -0,0 +1,82 @@
|
||||
// +build go1.8
|
||||
|
||||
package ec2query
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
func TestUnmarshalError(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Request *request.Request
|
||||
Code, Msg string
|
||||
ReqID string
|
||||
Status int
|
||||
}{
|
||||
"ErrorResponse": {
|
||||
Request: &request.Request{
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 400,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(strings.NewReader(
|
||||
`<Response>
|
||||
<Errors>
|
||||
<Error>
|
||||
<Code>codeAbc</Code>
|
||||
<Message>msg123</Message>
|
||||
</Error>
|
||||
</Errors>
|
||||
<RequestID>reqID123</RequestID>
|
||||
</Response>`)),
|
||||
},
|
||||
},
|
||||
Code: "codeAbc", Msg: "msg123",
|
||||
Status: 400, ReqID: "reqID123",
|
||||
},
|
||||
"unknown tag": {
|
||||
Request: &request.Request{
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 400,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(strings.NewReader(
|
||||
`<Hello>
|
||||
<World>.</World>
|
||||
</Hello>`)),
|
||||
},
|
||||
},
|
||||
Code: request.ErrCodeSerialization,
|
||||
Msg: "failed to unmarshal error message",
|
||||
Status: 400,
|
||||
},
|
||||
}
|
||||
|
||||
for name, c := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
r := c.Request
|
||||
UnmarshalError(r)
|
||||
if r.Error == nil {
|
||||
t.Fatalf("expect error, got none")
|
||||
}
|
||||
|
||||
aerr := r.Error.(awserr.RequestFailure)
|
||||
if e, a := c.Code, aerr.Code(); e != a {
|
||||
t.Errorf("expect %v code, got %v", e, a)
|
||||
}
|
||||
if e, a := c.Msg, aerr.Message(); e != a {
|
||||
t.Errorf("expect %q message, got %q", e, a)
|
||||
}
|
||||
if e, a := c.ReqID, aerr.RequestID(); e != a {
|
||||
t.Errorf("expect %v request ID, got %v", e, a)
|
||||
}
|
||||
if e, a := c.Status, aerr.StatusCode(); e != a {
|
||||
t.Errorf("expect %v status code, got %v", e, a)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+283
-47
@@ -75,7 +75,8 @@ func newOutputService1ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice1protocoltest",
|
||||
ServiceName: "OutputService1ProtocolTest",
|
||||
ServiceID: "OutputService1ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -108,7 +109,7 @@ const opOutputService1TestCaseOperation1 = "OperationName"
|
||||
// OutputService1TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService1TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -274,7 +275,8 @@ func newOutputService2ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice2protocoltest",
|
||||
ServiceName: "OutputService2ProtocolTest",
|
||||
ServiceID: "OutputService2ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -307,7 +309,7 @@ const opOutputService2TestCaseOperation1 = "OperationName"
|
||||
// OutputService2TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService2TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -418,7 +420,8 @@ func newOutputService3ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice3protocoltest",
|
||||
ServiceName: "OutputService3ProtocolTest",
|
||||
ServiceID: "OutputService3ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -451,7 +454,7 @@ const opOutputService3TestCaseOperation1 = "OperationName"
|
||||
// OutputService3TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService3TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -561,7 +564,8 @@ func newOutputService4ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice4protocoltest",
|
||||
ServiceName: "OutputService4ProtocolTest",
|
||||
ServiceID: "OutputService4ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -594,7 +598,7 @@ const opOutputService4TestCaseOperation1 = "OperationName"
|
||||
// OutputService4TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService4TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -704,7 +708,8 @@ func newOutputService5ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice5protocoltest",
|
||||
ServiceName: "OutputService5ProtocolTest",
|
||||
ServiceID: "OutputService5ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -737,7 +742,7 @@ const opOutputService5TestCaseOperation1 = "OperationName"
|
||||
// OutputService5TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService5TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -847,7 +852,8 @@ func newOutputService6ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice6protocoltest",
|
||||
ServiceName: "OutputService6ProtocolTest",
|
||||
ServiceID: "OutputService6ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -880,7 +886,7 @@ const opOutputService6TestCaseOperation1 = "OperationName"
|
||||
// OutputService6TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService6TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1002,7 +1008,8 @@ func newOutputService7ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice7protocoltest",
|
||||
ServiceName: "OutputService7ProtocolTest",
|
||||
ServiceID: "OutputService7ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1035,7 +1042,7 @@ const opOutputService7TestCaseOperation1 = "OperationName"
|
||||
// OutputService7TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService7TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1145,7 +1152,8 @@ func newOutputService8ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice8protocoltest",
|
||||
ServiceName: "OutputService8ProtocolTest",
|
||||
ServiceID: "OutputService8ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1178,7 +1186,7 @@ const opOutputService8TestCaseOperation1 = "OperationName"
|
||||
// OutputService8TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService8TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1288,7 +1296,8 @@ func newOutputService9ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice9protocoltest",
|
||||
ServiceName: "OutputService9ProtocolTest",
|
||||
ServiceID: "OutputService9ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1321,7 +1330,7 @@ const opOutputService9TestCaseOperation1 = "OperationName"
|
||||
// OutputService9TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService9TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1431,7 +1440,8 @@ func newOutputService10ProtocolTestClient(cfg aws.Config, handlers request.Handl
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice10protocoltest",
|
||||
ServiceName: "OutputService10ProtocolTest",
|
||||
ServiceID: "OutputService10ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1464,7 +1474,7 @@ const opOutputService10TestCaseOperation1 = "OperationName"
|
||||
// OutputService10TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService10TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1534,28 +1544,216 @@ type OutputService10TestShapeOutputService10TestCaseOperation1Input struct {
|
||||
type OutputService10TestShapeOutputService10TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
FooEnum *string `type:"string" enum:"OutputService10TestShapeEC2EnumType"`
|
||||
StructMember *OutputService10TestShapeTimeContainer `type:"structure"`
|
||||
|
||||
TimeArg *time.Time `type:"timestamp"`
|
||||
|
||||
TimeCustom *time.Time `type:"timestamp" timestampFormat:"rfc822"`
|
||||
|
||||
TimeFormat *time.Time `type:"timestamp" timestampFormat:"unixTimestamp"`
|
||||
}
|
||||
|
||||
// SetStructMember sets the StructMember field's value.
|
||||
func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetStructMember(v *OutputService10TestShapeTimeContainer) *OutputService10TestShapeOutputService10TestCaseOperation1Output {
|
||||
s.StructMember = v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeArg sets the TimeArg field's value.
|
||||
func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetTimeArg(v time.Time) *OutputService10TestShapeOutputService10TestCaseOperation1Output {
|
||||
s.TimeArg = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeCustom sets the TimeCustom field's value.
|
||||
func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetTimeCustom(v time.Time) *OutputService10TestShapeOutputService10TestCaseOperation1Output {
|
||||
s.TimeCustom = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeFormat sets the TimeFormat field's value.
|
||||
func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetTimeFormat(v time.Time) *OutputService10TestShapeOutputService10TestCaseOperation1Output {
|
||||
s.TimeFormat = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type OutputService10TestShapeTimeContainer struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
Bar *time.Time `locationName:"bar" type:"timestamp" timestampFormat:"unixTimestamp"`
|
||||
|
||||
Foo *time.Time `locationName:"foo" type:"timestamp"`
|
||||
}
|
||||
|
||||
// SetBar sets the Bar field's value.
|
||||
func (s *OutputService10TestShapeTimeContainer) SetBar(v time.Time) *OutputService10TestShapeTimeContainer {
|
||||
s.Bar = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetFoo sets the Foo field's value.
|
||||
func (s *OutputService10TestShapeTimeContainer) SetFoo(v time.Time) *OutputService10TestShapeTimeContainer {
|
||||
s.Foo = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// OutputService11ProtocolTest provides the API operation methods for making requests to
|
||||
// . See this package's package overview docs
|
||||
// for details on the service.
|
||||
//
|
||||
// OutputService11ProtocolTest methods are safe to use concurrently. It is not safe to
|
||||
// modify mutate any of the struct's properties though.
|
||||
type OutputService11ProtocolTest struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// New creates a new instance of the OutputService11ProtocolTest client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
// // Create a OutputService11ProtocolTest client from just a session.
|
||||
// svc := outputservice11protocoltest.New(mySession)
|
||||
//
|
||||
// // Create a OutputService11ProtocolTest client with additional configuration
|
||||
// svc := outputservice11protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func NewOutputService11ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService11ProtocolTest {
|
||||
c := p.ClientConfig("outputservice11protocoltest", cfgs...)
|
||||
return newOutputService11ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newOutputService11ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *OutputService11ProtocolTest {
|
||||
svc := &OutputService11ProtocolTest{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "OutputService11ProtocolTest",
|
||||
ServiceID: "OutputService11ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(ec2query.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(ec2query.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(ec2query.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(ec2query.UnmarshalErrorHandler)
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a OutputService11ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *OutputService11ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opOutputService11TestCaseOperation1 = "OperationName"
|
||||
|
||||
// OutputService11TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService11TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See OutputService11TestCaseOperation1 for more information on using the OutputService11TestCaseOperation1
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the OutputService11TestCaseOperation1Request method.
|
||||
// req, resp := client.OutputService11TestCaseOperation1Request(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *OutputService11ProtocolTest) OutputService11TestCaseOperation1Request(input *OutputService11TestShapeOutputService11TestCaseOperation1Input) (req *request.Request, output *OutputService11TestShapeOutputService11TestCaseOperation1Output) {
|
||||
op := &request.Operation{
|
||||
Name: opOutputService11TestCaseOperation1,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService11TestShapeOutputService11TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
output = &OutputService11TestShapeOutputService11TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
return
|
||||
}
|
||||
|
||||
// OutputService11TestCaseOperation1 API operation for .
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation OutputService11TestCaseOperation1 for usage and error information.
|
||||
func (c *OutputService11ProtocolTest) OutputService11TestCaseOperation1(input *OutputService11TestShapeOutputService11TestCaseOperation1Input) (*OutputService11TestShapeOutputService11TestCaseOperation1Output, error) {
|
||||
req, out := c.OutputService11TestCaseOperation1Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// OutputService11TestCaseOperation1WithContext is the same as OutputService11TestCaseOperation1 with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See OutputService11TestCaseOperation1 for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *OutputService11ProtocolTest) OutputService11TestCaseOperation1WithContext(ctx aws.Context, input *OutputService11TestShapeOutputService11TestCaseOperation1Input, opts ...request.Option) (*OutputService11TestShapeOutputService11TestCaseOperation1Output, error) {
|
||||
req, out := c.OutputService11TestCaseOperation1Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type OutputService11TestShapeOutputService11TestCaseOperation1Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService11TestShapeOutputService11TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
FooEnum *string `type:"string" enum:"OutputService11TestShapeEC2EnumType"`
|
||||
|
||||
ListEnums []*string `type:"list"`
|
||||
}
|
||||
|
||||
// SetFooEnum sets the FooEnum field's value.
|
||||
func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetFooEnum(v string) *OutputService10TestShapeOutputService10TestCaseOperation1Output {
|
||||
func (s *OutputService11TestShapeOutputService11TestCaseOperation1Output) SetFooEnum(v string) *OutputService11TestShapeOutputService11TestCaseOperation1Output {
|
||||
s.FooEnum = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetListEnums sets the ListEnums field's value.
|
||||
func (s *OutputService10TestShapeOutputService10TestCaseOperation1Output) SetListEnums(v []*string) *OutputService10TestShapeOutputService10TestCaseOperation1Output {
|
||||
func (s *OutputService11TestShapeOutputService11TestCaseOperation1Output) SetListEnums(v []*string) *OutputService11TestShapeOutputService11TestCaseOperation1Output {
|
||||
s.ListEnums = v
|
||||
return s
|
||||
}
|
||||
|
||||
const (
|
||||
// EC2EnumTypeFoo is a OutputService10TestShapeEC2EnumType enum value
|
||||
// EC2EnumTypeFoo is a OutputService11TestShapeEC2EnumType enum value
|
||||
EC2EnumTypeFoo = "foo"
|
||||
|
||||
// EC2EnumTypeBar is a OutputService10TestShapeEC2EnumType enum value
|
||||
// EC2EnumTypeBar is a OutputService11TestShapeEC2EnumType enum value
|
||||
EC2EnumTypeBar = "bar"
|
||||
)
|
||||
|
||||
@@ -1573,8 +1771,8 @@ func TestOutputService1ProtocolTestScalarMembersCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1620,8 +1818,8 @@ func TestOutputService2ProtocolTestBlobCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1646,8 +1844,8 @@ func TestOutputService3ProtocolTestListsCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1675,8 +1873,8 @@ func TestOutputService4ProtocolTestListWithCustomMemberNameCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1704,8 +1902,8 @@ func TestOutputService5ProtocolTestFlattenedListCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1733,8 +1931,8 @@ func TestOutputService6ProtocolTestNormalMapCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1762,8 +1960,8 @@ func TestOutputService7ProtocolTestFlattenedMapCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1791,8 +1989,8 @@ func TestOutputService8ProtocolTestNamedMapCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1820,8 +2018,8 @@ func TestOutputService9ProtocolTestEmptyStringCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1836,18 +2034,56 @@ func TestOutputService9ProtocolTestEmptyStringCase1(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService10ProtocolTestEnumOutputCase1(t *testing.T) {
|
||||
func TestOutputService10ProtocolTestTimestampMembersCase1(t *testing.T) {
|
||||
svc := NewOutputService10ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><FooEnum>foo</FooEnum><ListEnums><member>foo</member><member>bar</member></ListEnums></OperationNameResponse>"))
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><StructMember><foo>2014-04-29T18:30:38Z</foo><bar>1398796238</bar></StructMember><TimeArg>2014-04-29T18:30:38Z</TimeArg><TimeCustom>Tue, 29 Apr 2014 18:30:38 GMT</TimeCustom><TimeFormat>1398796238</TimeFormat><RequestId>requestid</RequestId></OperationNameResponse>"))
|
||||
req, out := svc.OutputService10TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
ec2query.UnmarshalMeta(req)
|
||||
ec2query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
|
||||
// assert response
|
||||
if out == nil {
|
||||
t.Errorf("expect not to be nil")
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.StructMember.Bar.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.StructMember.Foo.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.TimeArg.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.TimeCustom.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.TimeFormat.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService11ProtocolTestEnumOutputCase1(t *testing.T) {
|
||||
svc := NewOutputService11ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><FooEnum>foo</FooEnum><ListEnums><member>foo</member><member>bar</member></ListEnums></OperationNameResponse>"))
|
||||
req, out := svc.OutputService11TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type decodedMessage struct {
|
||||
rawMessage
|
||||
Headers decodedHeaders `json:"headers"`
|
||||
}
|
||||
type jsonMessage struct {
|
||||
Length json.Number `json:"total_length"`
|
||||
HeadersLen json.Number `json:"headers_length"`
|
||||
PreludeCRC json.Number `json:"prelude_crc"`
|
||||
Headers decodedHeaders `json:"headers"`
|
||||
Payload []byte `json:"payload"`
|
||||
CRC json.Number `json:"message_crc"`
|
||||
}
|
||||
|
||||
func (d *decodedMessage) UnmarshalJSON(b []byte) (err error) {
|
||||
var jsonMsg jsonMessage
|
||||
if err = json.Unmarshal(b, &jsonMsg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.Length, err = numAsUint32(jsonMsg.Length)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.HeadersLen, err = numAsUint32(jsonMsg.HeadersLen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.PreludeCRC, err = numAsUint32(jsonMsg.PreludeCRC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Headers = jsonMsg.Headers
|
||||
d.Payload = jsonMsg.Payload
|
||||
d.CRC, err = numAsUint32(jsonMsg.CRC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *decodedMessage) MarshalJSON() ([]byte, error) {
|
||||
jsonMsg := jsonMessage{
|
||||
Length: json.Number(strconv.Itoa(int(d.Length))),
|
||||
HeadersLen: json.Number(strconv.Itoa(int(d.HeadersLen))),
|
||||
PreludeCRC: json.Number(strconv.Itoa(int(d.PreludeCRC))),
|
||||
Headers: d.Headers,
|
||||
Payload: d.Payload,
|
||||
CRC: json.Number(strconv.Itoa(int(d.CRC))),
|
||||
}
|
||||
|
||||
return json.Marshal(jsonMsg)
|
||||
}
|
||||
|
||||
func numAsUint32(n json.Number) (uint32, error) {
|
||||
v, err := n.Int64()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to get int64 json number, %v", err)
|
||||
}
|
||||
|
||||
return uint32(v), nil
|
||||
}
|
||||
|
||||
func (d decodedMessage) Message() Message {
|
||||
return Message{
|
||||
Headers: Headers(d.Headers),
|
||||
Payload: d.Payload,
|
||||
}
|
||||
}
|
||||
|
||||
type decodedHeaders Headers
|
||||
|
||||
func (hs *decodedHeaders) UnmarshalJSON(b []byte) error {
|
||||
var jsonHeaders []struct {
|
||||
Name string `json:"name"`
|
||||
Type valueType `json:"type"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(bytes.NewReader(b))
|
||||
decoder.UseNumber()
|
||||
if err := decoder.Decode(&jsonHeaders); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var headers Headers
|
||||
for _, h := range jsonHeaders {
|
||||
value, err := valueFromType(h.Type, h.Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
headers.Set(h.Name, value)
|
||||
}
|
||||
(*hs) = decodedHeaders(headers)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func valueFromType(typ valueType, val interface{}) (Value, error) {
|
||||
switch typ {
|
||||
case trueValueType:
|
||||
return BoolValue(true), nil
|
||||
case falseValueType:
|
||||
return BoolValue(false), nil
|
||||
case int8ValueType:
|
||||
v, err := val.(json.Number).Int64()
|
||||
return Int8Value(int8(v)), err
|
||||
case int16ValueType:
|
||||
v, err := val.(json.Number).Int64()
|
||||
return Int16Value(int16(v)), err
|
||||
case int32ValueType:
|
||||
v, err := val.(json.Number).Int64()
|
||||
return Int32Value(int32(v)), err
|
||||
case int64ValueType:
|
||||
v, err := val.(json.Number).Int64()
|
||||
return Int64Value(v), err
|
||||
case bytesValueType:
|
||||
v, err := base64.StdEncoding.DecodeString(val.(string))
|
||||
return BytesValue(v), err
|
||||
case stringValueType:
|
||||
v, err := base64.StdEncoding.DecodeString(val.(string))
|
||||
return StringValue(string(v)), err
|
||||
case timestampValueType:
|
||||
v, err := val.(json.Number).Int64()
|
||||
return TimestampValue(timeFromEpochMilli(v)), err
|
||||
case uuidValueType:
|
||||
v, err := base64.StdEncoding.DecodeString(val.(string))
|
||||
var tv UUIDValue
|
||||
copy(tv[:], v)
|
||||
return tv, err
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown type, %s, %T", typ.String(), val))
|
||||
}
|
||||
}
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash"
|
||||
"hash/crc32"
|
||||
"io"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
// Decoder provides decoding of an Event Stream messages.
|
||||
type Decoder struct {
|
||||
r io.Reader
|
||||
logger aws.Logger
|
||||
}
|
||||
|
||||
// NewDecoder initializes and returns a Decoder for decoding event
|
||||
// stream messages from the reader provided.
|
||||
func NewDecoder(r io.Reader) *Decoder {
|
||||
return &Decoder{
|
||||
r: r,
|
||||
}
|
||||
}
|
||||
|
||||
// Decode attempts to decode a single message from the event stream reader.
|
||||
// Will return the event stream message, or error if Decode fails to read
|
||||
// the message from the stream.
|
||||
func (d *Decoder) Decode(payloadBuf []byte) (m Message, err error) {
|
||||
reader := d.r
|
||||
if d.logger != nil {
|
||||
debugMsgBuf := bytes.NewBuffer(nil)
|
||||
reader = io.TeeReader(reader, debugMsgBuf)
|
||||
defer func() {
|
||||
logMessageDecode(d.logger, debugMsgBuf, m, err)
|
||||
}()
|
||||
}
|
||||
|
||||
crc := crc32.New(crc32IEEETable)
|
||||
hashReader := io.TeeReader(reader, crc)
|
||||
|
||||
prelude, err := decodePrelude(hashReader, crc)
|
||||
if err != nil {
|
||||
return Message{}, err
|
||||
}
|
||||
|
||||
if prelude.HeadersLen > 0 {
|
||||
lr := io.LimitReader(hashReader, int64(prelude.HeadersLen))
|
||||
m.Headers, err = decodeHeaders(lr)
|
||||
if err != nil {
|
||||
return Message{}, err
|
||||
}
|
||||
}
|
||||
|
||||
if payloadLen := prelude.PayloadLen(); payloadLen > 0 {
|
||||
buf, err := decodePayload(payloadBuf, io.LimitReader(hashReader, int64(payloadLen)))
|
||||
if err != nil {
|
||||
return Message{}, err
|
||||
}
|
||||
m.Payload = buf
|
||||
}
|
||||
|
||||
msgCRC := crc.Sum32()
|
||||
if err := validateCRC(reader, msgCRC); err != nil {
|
||||
return Message{}, err
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UseLogger specifies the Logger that that the decoder should use to log the
|
||||
// message decode to.
|
||||
func (d *Decoder) UseLogger(logger aws.Logger) {
|
||||
d.logger = logger
|
||||
}
|
||||
|
||||
func logMessageDecode(logger aws.Logger, msgBuf *bytes.Buffer, msg Message, decodeErr error) {
|
||||
w := bytes.NewBuffer(nil)
|
||||
defer func() { logger.Log(w.String()) }()
|
||||
|
||||
fmt.Fprintf(w, "Raw message:\n%s\n",
|
||||
hex.Dump(msgBuf.Bytes()))
|
||||
|
||||
if decodeErr != nil {
|
||||
fmt.Fprintf(w, "Decode error: %v\n", decodeErr)
|
||||
return
|
||||
}
|
||||
|
||||
rawMsg, err := msg.rawMessage()
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, "failed to create raw message, %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
decodedMsg := decodedMessage{
|
||||
rawMessage: rawMsg,
|
||||
Headers: decodedHeaders(msg.Headers),
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "Decoded message:\n")
|
||||
encoder := json.NewEncoder(w)
|
||||
if err := encoder.Encode(decodedMsg); err != nil {
|
||||
fmt.Fprintf(w, "failed to generate decoded message, %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func decodePrelude(r io.Reader, crc hash.Hash32) (messagePrelude, error) {
|
||||
var p messagePrelude
|
||||
|
||||
var err error
|
||||
p.Length, err = decodeUint32(r)
|
||||
if err != nil {
|
||||
return messagePrelude{}, err
|
||||
}
|
||||
|
||||
p.HeadersLen, err = decodeUint32(r)
|
||||
if err != nil {
|
||||
return messagePrelude{}, err
|
||||
}
|
||||
|
||||
if err := p.ValidateLens(); err != nil {
|
||||
return messagePrelude{}, err
|
||||
}
|
||||
|
||||
preludeCRC := crc.Sum32()
|
||||
if err := validateCRC(r, preludeCRC); err != nil {
|
||||
return messagePrelude{}, err
|
||||
}
|
||||
|
||||
p.PreludeCRC = preludeCRC
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func decodePayload(buf []byte, r io.Reader) ([]byte, error) {
|
||||
w := bytes.NewBuffer(buf[0:0])
|
||||
|
||||
_, err := io.Copy(w, r)
|
||||
return w.Bytes(), err
|
||||
}
|
||||
|
||||
func decodeUint8(r io.Reader) (uint8, error) {
|
||||
type byteReader interface {
|
||||
ReadByte() (byte, error)
|
||||
}
|
||||
|
||||
if br, ok := r.(byteReader); ok {
|
||||
v, err := br.ReadByte()
|
||||
return uint8(v), err
|
||||
}
|
||||
|
||||
var b [1]byte
|
||||
_, err := io.ReadFull(r, b[:])
|
||||
return uint8(b[0]), err
|
||||
}
|
||||
func decodeUint16(r io.Reader) (uint16, error) {
|
||||
var b [2]byte
|
||||
bs := b[:]
|
||||
_, err := io.ReadFull(r, bs)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return binary.BigEndian.Uint16(bs), nil
|
||||
}
|
||||
func decodeUint32(r io.Reader) (uint32, error) {
|
||||
var b [4]byte
|
||||
bs := b[:]
|
||||
_, err := io.ReadFull(r, bs)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return binary.BigEndian.Uint32(bs), nil
|
||||
}
|
||||
func decodeUint64(r io.Reader) (uint64, error) {
|
||||
var b [8]byte
|
||||
bs := b[:]
|
||||
_, err := io.ReadFull(r, bs)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return binary.BigEndian.Uint64(bs), nil
|
||||
}
|
||||
|
||||
func validateCRC(r io.Reader, expect uint32) error {
|
||||
msgCRC, err := decodeUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if msgCRC != expect {
|
||||
return ChecksumError{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestWriteEncodedFromDecoded(t *testing.T) {
|
||||
cases, err := readPositiveTests("testdata")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load positive tests, %v", err)
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
f, err := os.Create(filepath.Join("testdata", "encoded", "positive", c.Name))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open %q, %v", c.Name, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
encoder := NewEncoder(f)
|
||||
|
||||
msg := c.Decoded.Message()
|
||||
if err := encoder.Encode(msg); err != nil {
|
||||
t.Errorf("failed to encode %q, %v", c.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecoder_Decode(t *testing.T) {
|
||||
cases, err := readPositiveTests("testdata")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load positive tests, %v", err)
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
decoder := NewDecoder(bytes.NewBuffer(c.Encoded))
|
||||
|
||||
msg, err := decoder.Decode(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("%s, expect no decode error, got %v", c.Name, err)
|
||||
}
|
||||
|
||||
raw, err := msg.rawMessage() // rawMessage will fail if payload read CRC fails
|
||||
if err != nil {
|
||||
t.Fatalf("%s, failed to get raw decoded message %v", c.Name, err)
|
||||
}
|
||||
|
||||
if e, a := c.Decoded.Length, raw.Length; e != a {
|
||||
t.Errorf("%s, expect %v length, got %v", c.Name, e, a)
|
||||
}
|
||||
if e, a := c.Decoded.HeadersLen, raw.HeadersLen; e != a {
|
||||
t.Errorf("%s, expect %v HeadersLen, got %v", c.Name, e, a)
|
||||
}
|
||||
if e, a := c.Decoded.PreludeCRC, raw.PreludeCRC; e != a {
|
||||
t.Errorf("%s, expect %v PreludeCRC, got %v", c.Name, e, a)
|
||||
}
|
||||
if e, a := Headers(c.Decoded.Headers), msg.Headers; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%s, expect %v headers, got %v", c.Name, e, a)
|
||||
}
|
||||
if e, a := c.Decoded.Payload, raw.Payload; !bytes.Equal(e, a) {
|
||||
t.Errorf("%s, expect %v payload, got %v", c.Name, e, a)
|
||||
}
|
||||
if e, a := c.Decoded.CRC, raw.CRC; e != a {
|
||||
t.Errorf("%s, expect %v CRC, got %v", c.Name, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecoder_Decode_Negative(t *testing.T) {
|
||||
cases, err := readNegativeTests("testdata")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load negative tests, %v", err)
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
decoder := NewDecoder(bytes.NewBuffer(c.Encoded))
|
||||
|
||||
msg, err := decoder.Decode(nil)
|
||||
if err == nil {
|
||||
rawMsg, rawMsgErr := msg.rawMessage()
|
||||
t.Fatalf("%s, expect error, got none, %s,\n%s\n%#v, %v\n", c.Name,
|
||||
c.Err, hex.Dump(c.Encoded), rawMsg, rawMsgErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var testEncodedMsg = []byte{0, 0, 0, 61, 0, 0, 0, 32, 7, 253, 131, 150, 12, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 7, 0, 16, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 106, 115, 111, 110, 123, 39, 102, 111, 111, 39, 58, 39, 98, 97, 114, 39, 125, 141, 156, 8, 177}
|
||||
|
||||
func TestDecoder_DecodeMultipleMessages(t *testing.T) {
|
||||
const (
|
||||
expectMsgCount = 10
|
||||
expectPayloadLen = 13
|
||||
)
|
||||
|
||||
r := bytes.NewBuffer(nil)
|
||||
for i := 0; i < expectMsgCount; i++ {
|
||||
r.Write(testEncodedMsg)
|
||||
}
|
||||
|
||||
decoder := NewDecoder(r)
|
||||
|
||||
var err error
|
||||
var msg Message
|
||||
var count int
|
||||
for {
|
||||
msg, err = decoder.Decode(nil)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
count++
|
||||
|
||||
if e, a := expectPayloadLen, len(msg.Payload); e != a {
|
||||
t.Errorf("expect %v payload len, got %v", e, a)
|
||||
}
|
||||
|
||||
if e, a := []byte(`{'foo':'bar'}`), msg.Payload; !bytes.Equal(e, a) {
|
||||
t.Errorf("expect %v payload, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
type causer interface {
|
||||
Cause() error
|
||||
}
|
||||
if err != nil && count != expectMsgCount {
|
||||
t.Fatalf("expect, no error, got %v", err)
|
||||
}
|
||||
|
||||
if e, a := expectMsgCount, count; e != a {
|
||||
t.Errorf("expect %v messages read, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecode(b *testing.B) {
|
||||
r := bytes.NewReader(testEncodedMsg)
|
||||
decoder := NewDecoder(r)
|
||||
payloadBuf := make([]byte, 0, 5*1024)
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
msg, err := decoder.Decode(payloadBuf)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
// Release the payload buffer
|
||||
payloadBuf = msg.Payload[0:0]
|
||||
r.Seek(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkDecode_NoPayloadBuf(b *testing.B) {
|
||||
r := bytes.NewReader(testEncodedMsg)
|
||||
decoder := NewDecoder(r)
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := decoder.Decode(nil)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
r.Seek(0, 0)
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"hash"
|
||||
"hash/crc32"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Encoder provides EventStream message encoding.
|
||||
type Encoder struct {
|
||||
w io.Writer
|
||||
|
||||
headersBuf *bytes.Buffer
|
||||
}
|
||||
|
||||
// NewEncoder initializes and returns an Encoder to encode Event Stream
|
||||
// messages to an io.Writer.
|
||||
func NewEncoder(w io.Writer) *Encoder {
|
||||
return &Encoder{
|
||||
w: w,
|
||||
headersBuf: bytes.NewBuffer(nil),
|
||||
}
|
||||
}
|
||||
|
||||
// Encode encodes a single EventStream message to the io.Writer the Encoder
|
||||
// was created with. An error is returned if writing the message fails.
|
||||
func (e *Encoder) Encode(msg Message) error {
|
||||
e.headersBuf.Reset()
|
||||
|
||||
err := encodeHeaders(e.headersBuf, msg.Headers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
crc := crc32.New(crc32IEEETable)
|
||||
hashWriter := io.MultiWriter(e.w, crc)
|
||||
|
||||
headersLen := uint32(e.headersBuf.Len())
|
||||
payloadLen := uint32(len(msg.Payload))
|
||||
|
||||
if err := encodePrelude(hashWriter, crc, headersLen, payloadLen); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if headersLen > 0 {
|
||||
if _, err := io.Copy(hashWriter, e.headersBuf); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if payloadLen > 0 {
|
||||
if _, err := hashWriter.Write(msg.Payload); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
msgCRC := crc.Sum32()
|
||||
return binary.Write(e.w, binary.BigEndian, msgCRC)
|
||||
}
|
||||
|
||||
func encodePrelude(w io.Writer, crc hash.Hash32, headersLen, payloadLen uint32) error {
|
||||
p := messagePrelude{
|
||||
Length: minMsgLen + headersLen + payloadLen,
|
||||
HeadersLen: headersLen,
|
||||
}
|
||||
if err := p.ValidateLens(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := binaryWriteFields(w, binary.BigEndian,
|
||||
p.Length,
|
||||
p.HeadersLen,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.PreludeCRC = crc.Sum32()
|
||||
err = binary.Write(w, binary.BigEndian, p.PreludeCRC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func encodeHeaders(w io.Writer, headers Headers) error {
|
||||
for _, h := range headers {
|
||||
hn := headerName{
|
||||
Len: uint8(len(h.Name)),
|
||||
}
|
||||
copy(hn.Name[:hn.Len], h.Name)
|
||||
if err := hn.encode(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := h.Value.encode(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func binaryWriteFields(w io.Writer, order binary.ByteOrder, vs ...interface{}) error {
|
||||
for _, v := range vs {
|
||||
if err := binary.Write(w, order, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEncoder_Encode(t *testing.T) {
|
||||
cases, err := readPositiveTests("testdata")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load positive tests, %v", err)
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
var w bytes.Buffer
|
||||
encoder := NewEncoder(&w)
|
||||
|
||||
err = encoder.Encode(c.Decoded.Message())
|
||||
if err != nil {
|
||||
t.Fatalf("%s, failed to encode message, %v", c.Name, err)
|
||||
}
|
||||
|
||||
if e, a := c.Encoded, w.Bytes(); !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%s, expect:\n%v\nactual:\n%v\n", c.Name,
|
||||
hex.Dump(e), hex.Dump(a))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncode(b *testing.B) {
|
||||
var w bytes.Buffer
|
||||
encoder := NewEncoder(&w)
|
||||
msg := Message{
|
||||
Headers: Headers{
|
||||
{Name: "event-id", Value: Int16Value(123)},
|
||||
},
|
||||
Payload: []byte(`{"abc":123}`),
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
err := encoder.Encode(msg)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package eventstream
|
||||
|
||||
import "fmt"
|
||||
|
||||
// LengthError provides the error for items being larger than a maximum length.
|
||||
type LengthError struct {
|
||||
Part string
|
||||
Want int
|
||||
Have int
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
func (e LengthError) Error() string {
|
||||
return fmt.Sprintf("%s length invalid, %d/%d, %v",
|
||||
e.Part, e.Want, e.Have, e.Value)
|
||||
}
|
||||
|
||||
// ChecksumError provides the error for message checksum invalidation errors.
|
||||
type ChecksumError struct{}
|
||||
|
||||
func (e ChecksumError) Error() string {
|
||||
return "message checksum mismatch"
|
||||
}
|
||||
Generated
Vendored
+196
@@ -0,0 +1,196 @@
|
||||
package eventstreamapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream"
|
||||
)
|
||||
|
||||
// Unmarshaler provides the interface for unmarshaling a EventStream
|
||||
// message into a SDK type.
|
||||
type Unmarshaler interface {
|
||||
UnmarshalEvent(protocol.PayloadUnmarshaler, eventstream.Message) error
|
||||
}
|
||||
|
||||
// EventStream headers with specific meaning to async API functionality.
|
||||
const (
|
||||
MessageTypeHeader = `:message-type` // Identifies type of message.
|
||||
EventMessageType = `event`
|
||||
ErrorMessageType = `error`
|
||||
ExceptionMessageType = `exception`
|
||||
|
||||
// Message Events
|
||||
EventTypeHeader = `:event-type` // Identifies message event type e.g. "Stats".
|
||||
|
||||
// Message Error
|
||||
ErrorCodeHeader = `:error-code`
|
||||
ErrorMessageHeader = `:error-message`
|
||||
|
||||
// Message Exception
|
||||
ExceptionTypeHeader = `:exception-type`
|
||||
)
|
||||
|
||||
// EventReader provides reading from the EventStream of an reader.
|
||||
type EventReader struct {
|
||||
reader io.ReadCloser
|
||||
decoder *eventstream.Decoder
|
||||
|
||||
unmarshalerForEventType func(string) (Unmarshaler, error)
|
||||
payloadUnmarshaler protocol.PayloadUnmarshaler
|
||||
|
||||
payloadBuf []byte
|
||||
}
|
||||
|
||||
// NewEventReader returns a EventReader built from the reader and unmarshaler
|
||||
// provided. Use ReadStream method to start reading from the EventStream.
|
||||
func NewEventReader(
|
||||
reader io.ReadCloser,
|
||||
payloadUnmarshaler protocol.PayloadUnmarshaler,
|
||||
unmarshalerForEventType func(string) (Unmarshaler, error),
|
||||
) *EventReader {
|
||||
return &EventReader{
|
||||
reader: reader,
|
||||
decoder: eventstream.NewDecoder(reader),
|
||||
payloadUnmarshaler: payloadUnmarshaler,
|
||||
unmarshalerForEventType: unmarshalerForEventType,
|
||||
payloadBuf: make([]byte, 10*1024),
|
||||
}
|
||||
}
|
||||
|
||||
// UseLogger instructs the EventReader to use the logger and log level
|
||||
// specified.
|
||||
func (r *EventReader) UseLogger(logger aws.Logger, logLevel aws.LogLevelType) {
|
||||
if logger != nil && logLevel.Matches(aws.LogDebugWithEventStreamBody) {
|
||||
r.decoder.UseLogger(logger)
|
||||
}
|
||||
}
|
||||
|
||||
// ReadEvent attempts to read a message from the EventStream and return the
|
||||
// unmarshaled event value that the message is for.
|
||||
//
|
||||
// For EventStream API errors check if the returned error satisfies the
|
||||
// awserr.Error interface to get the error's Code and Message components.
|
||||
//
|
||||
// EventUnmarshalers called with EventStream messages must take copies of the
|
||||
// message's Payload. The payload will is reused between events read.
|
||||
func (r *EventReader) ReadEvent() (event interface{}, err error) {
|
||||
msg, err := r.decoder.Decode(r.payloadBuf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
// Reclaim payload buffer for next message read.
|
||||
r.payloadBuf = msg.Payload[0:0]
|
||||
}()
|
||||
|
||||
typ, err := GetHeaderString(msg, MessageTypeHeader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch typ {
|
||||
case EventMessageType:
|
||||
return r.unmarshalEventMessage(msg)
|
||||
case ExceptionMessageType:
|
||||
err = r.unmarshalEventException(msg)
|
||||
return nil, err
|
||||
case ErrorMessageType:
|
||||
return nil, r.unmarshalErrorMessage(msg)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown eventstream message type, %v", typ)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *EventReader) unmarshalEventMessage(
|
||||
msg eventstream.Message,
|
||||
) (event interface{}, err error) {
|
||||
eventType, err := GetHeaderString(msg, EventTypeHeader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ev, err := r.unmarshalerForEventType(eventType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = ev.UnmarshalEvent(r.payloadUnmarshaler, msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ev, nil
|
||||
}
|
||||
|
||||
func (r *EventReader) unmarshalEventException(
|
||||
msg eventstream.Message,
|
||||
) (err error) {
|
||||
eventType, err := GetHeaderString(msg, ExceptionTypeHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ev, err := r.unmarshalerForEventType(eventType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ev.UnmarshalEvent(r.payloadUnmarshaler, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var ok bool
|
||||
err, ok = ev.(error)
|
||||
if !ok {
|
||||
err = messageError{
|
||||
code: "SerializationError",
|
||||
msg: fmt.Sprintf(
|
||||
"event stream exception %s mapped to non-error %T, %v",
|
||||
eventType, ev, ev,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *EventReader) unmarshalErrorMessage(msg eventstream.Message) (err error) {
|
||||
var msgErr messageError
|
||||
|
||||
msgErr.code, err = GetHeaderString(msg, ErrorCodeHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgErr.msg, err = GetHeaderString(msg, ErrorMessageHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return msgErr
|
||||
}
|
||||
|
||||
// Close closes the EventReader's EventStream reader.
|
||||
func (r *EventReader) Close() error {
|
||||
return r.reader.Close()
|
||||
}
|
||||
|
||||
// GetHeaderString returns the value of the header as a string. If the header
|
||||
// is not set or the value is not a string an error will be returned.
|
||||
func GetHeaderString(msg eventstream.Message, headerName string) (string, error) {
|
||||
headerVal := msg.Headers.Get(headerName)
|
||||
if headerVal == nil {
|
||||
return "", fmt.Errorf("error header %s not present", headerName)
|
||||
}
|
||||
|
||||
v, ok := headerVal.Get().(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("error header value is not a string, %T", headerVal)
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
Generated
Vendored
+253
@@ -0,0 +1,253 @@
|
||||
package eventstreamapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/restjson"
|
||||
)
|
||||
|
||||
var eventMessageTypeHeader = eventstream.Header{
|
||||
Name: MessageTypeHeader,
|
||||
Value: eventstream.StringValue(EventMessageType),
|
||||
}
|
||||
|
||||
func TestEventReader(t *testing.T) {
|
||||
stream := createStream(
|
||||
eventstream.Message{
|
||||
Headers: eventstream.Headers{
|
||||
eventMessageTypeHeader,
|
||||
eventstream.Header{
|
||||
Name: EventTypeHeader,
|
||||
Value: eventstream.StringValue("eventABC"),
|
||||
},
|
||||
},
|
||||
},
|
||||
eventstream.Message{
|
||||
Headers: eventstream.Headers{
|
||||
eventMessageTypeHeader,
|
||||
eventstream.Header{
|
||||
Name: EventTypeHeader,
|
||||
Value: eventstream.StringValue("eventEFG"),
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
var unmarshalers request.HandlerList
|
||||
unmarshalers.PushBackNamed(restjson.UnmarshalHandler)
|
||||
|
||||
eventReader := NewEventReader(stream,
|
||||
protocol.HandlerPayloadUnmarshal{
|
||||
Unmarshalers: unmarshalers,
|
||||
},
|
||||
unmarshalerForEventType,
|
||||
)
|
||||
|
||||
event, err := eventReader.ReadEvent()
|
||||
if err != nil {
|
||||
t.Fatalf("expect no error, got %v", err)
|
||||
}
|
||||
|
||||
if event == nil {
|
||||
t.Fatalf("expect event got none")
|
||||
}
|
||||
|
||||
event, err = eventReader.ReadEvent()
|
||||
if err == nil {
|
||||
t.Fatalf("expect error for unknown event, got none")
|
||||
}
|
||||
|
||||
if event != nil {
|
||||
t.Fatalf("expect no event, got %T, %v", event, event)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEventReader_Error(t *testing.T) {
|
||||
stream := createStream(
|
||||
eventstream.Message{
|
||||
Headers: eventstream.Headers{
|
||||
eventstream.Header{
|
||||
Name: MessageTypeHeader,
|
||||
Value: eventstream.StringValue(ErrorMessageType),
|
||||
},
|
||||
eventstream.Header{
|
||||
Name: ErrorCodeHeader,
|
||||
Value: eventstream.StringValue("errorCode"),
|
||||
},
|
||||
eventstream.Header{
|
||||
Name: ErrorMessageHeader,
|
||||
Value: eventstream.StringValue("error message occur"),
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
var unmarshalers request.HandlerList
|
||||
unmarshalers.PushBackNamed(restjson.UnmarshalHandler)
|
||||
|
||||
eventReader := NewEventReader(stream,
|
||||
protocol.HandlerPayloadUnmarshal{
|
||||
Unmarshalers: unmarshalers,
|
||||
},
|
||||
unmarshalerForEventType,
|
||||
)
|
||||
|
||||
event, err := eventReader.ReadEvent()
|
||||
if err == nil {
|
||||
t.Fatalf("expect error got none")
|
||||
}
|
||||
|
||||
if event != nil {
|
||||
t.Fatalf("expect no event, got %v", event)
|
||||
}
|
||||
|
||||
if e, a := "errorCode: error message occur", err.Error(); e != a {
|
||||
t.Errorf("expect %v error, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEventReader_Exception(t *testing.T) {
|
||||
eventMsgs := []eventstream.Message{
|
||||
{
|
||||
Headers: eventstream.Headers{
|
||||
eventstream.Header{
|
||||
Name: MessageTypeHeader,
|
||||
Value: eventstream.StringValue(ExceptionMessageType),
|
||||
},
|
||||
eventstream.Header{
|
||||
Name: ExceptionTypeHeader,
|
||||
Value: eventstream.StringValue("exception"),
|
||||
},
|
||||
},
|
||||
Payload: []byte(`{"message":"exception message"}`),
|
||||
},
|
||||
}
|
||||
stream := createStream(eventMsgs...)
|
||||
|
||||
var unmarshalers request.HandlerList
|
||||
unmarshalers.PushBackNamed(restjson.UnmarshalHandler)
|
||||
|
||||
eventReader := NewEventReader(stream,
|
||||
protocol.HandlerPayloadUnmarshal{
|
||||
Unmarshalers: unmarshalers,
|
||||
},
|
||||
unmarshalerForEventType,
|
||||
)
|
||||
|
||||
event, err := eventReader.ReadEvent()
|
||||
if err == nil {
|
||||
t.Fatalf("expect error got none")
|
||||
}
|
||||
|
||||
if event != nil {
|
||||
t.Fatalf("expect no event, got %v", event)
|
||||
}
|
||||
|
||||
et := err.(*exceptionType)
|
||||
if e, a := string(eventMsgs[0].Payload), string(et.Payload); e != a {
|
||||
t.Errorf("expect %v payload, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEventReader(b *testing.B) {
|
||||
var buf bytes.Buffer
|
||||
encoder := eventstream.NewEncoder(&buf)
|
||||
msg := eventstream.Message{
|
||||
Headers: eventstream.Headers{
|
||||
eventMessageTypeHeader,
|
||||
eventstream.Header{
|
||||
Name: EventTypeHeader,
|
||||
Value: eventstream.StringValue("eventABC"),
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := encoder.Encode(msg); err != nil {
|
||||
b.Fatalf("failed to encode message, %v", err)
|
||||
}
|
||||
stream := bytes.NewReader(buf.Bytes())
|
||||
|
||||
var unmarshalers request.HandlerList
|
||||
unmarshalers.PushBackNamed(restjson.UnmarshalHandler)
|
||||
|
||||
eventReader := NewEventReader(ioutil.NopCloser(stream),
|
||||
protocol.HandlerPayloadUnmarshal{
|
||||
Unmarshalers: unmarshalers,
|
||||
},
|
||||
unmarshalerForEventType,
|
||||
)
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
stream.Seek(0, 0)
|
||||
|
||||
event, err := eventReader.ReadEvent()
|
||||
if err != nil {
|
||||
b.Fatalf("expect no error, got %v", err)
|
||||
}
|
||||
if event == nil {
|
||||
b.Fatalf("expect event got none")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalerForEventType(eventType string) (Unmarshaler, error) {
|
||||
switch eventType {
|
||||
case "eventABC":
|
||||
return &eventABC{}, nil
|
||||
case "exception":
|
||||
return &exceptionType{}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown event type, %v", eventType)
|
||||
}
|
||||
}
|
||||
|
||||
type eventABC struct {
|
||||
_ struct{}
|
||||
|
||||
HeaderField string
|
||||
Payload []byte
|
||||
}
|
||||
|
||||
func (e *eventABC) UnmarshalEvent(
|
||||
unmarshaler protocol.PayloadUnmarshaler,
|
||||
msg eventstream.Message,
|
||||
) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func createStream(msgs ...eventstream.Message) io.ReadCloser {
|
||||
w := bytes.NewBuffer(nil)
|
||||
|
||||
encoder := eventstream.NewEncoder(w)
|
||||
|
||||
for _, msg := range msgs {
|
||||
if err := encoder.Encode(msg); err != nil {
|
||||
panic("createStream failed, " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return ioutil.NopCloser(w)
|
||||
}
|
||||
|
||||
type exceptionType struct {
|
||||
Payload []byte
|
||||
}
|
||||
|
||||
func (e exceptionType) Error() string {
|
||||
return fmt.Sprintf("exception error message")
|
||||
}
|
||||
|
||||
func (e *exceptionType) UnmarshalEvent(
|
||||
unmarshaler protocol.PayloadUnmarshaler,
|
||||
msg eventstream.Message,
|
||||
) error {
|
||||
e.Payload = msg.Payload
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
package eventstreamapi
|
||||
|
||||
import "fmt"
|
||||
|
||||
type messageError struct {
|
||||
code string
|
||||
msg string
|
||||
}
|
||||
|
||||
func (e messageError) Code() string {
|
||||
return e.code
|
||||
}
|
||||
|
||||
func (e messageError) Message() string {
|
||||
return e.msg
|
||||
}
|
||||
|
||||
func (e messageError) Error() string {
|
||||
return fmt.Sprintf("%s: %s", e.code, e.msg)
|
||||
}
|
||||
|
||||
func (e messageError) OrigErr() error {
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
// +build !go1.10
|
||||
|
||||
package eventstreamtest
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
)
|
||||
|
||||
// /x/net/http2 is only available for the latest two versions of Go. Any Go
|
||||
// version older than that cannot use the utility to configure the http2
|
||||
// server.
|
||||
func setupServer(server *httptest.Server, useH2 bool) *http.Client {
|
||||
server.Start()
|
||||
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+40
@@ -0,0 +1,40 @@
|
||||
// +build go1.10
|
||||
|
||||
package eventstreamtest
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
||||
"golang.org/x/net/http2"
|
||||
)
|
||||
|
||||
// /x/net/http2 is only available for the latest two versions of Go. Any Go
|
||||
// version older than that cannot use the utility to configure the http2
|
||||
// server.
|
||||
func setupServer(server *httptest.Server, useH2 bool) *http.Client {
|
||||
server.Config.TLSConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
clientTrans := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
}
|
||||
|
||||
if useH2 {
|
||||
http2.ConfigureServer(server.Config, nil)
|
||||
http2.ConfigureTransport(clientTrans)
|
||||
server.Config.TLSConfig.NextProtos = []string{http2.NextProtoTLS}
|
||||
clientTrans.TLSClientConfig.NextProtos = []string{http2.NextProtoTLS}
|
||||
}
|
||||
server.TLS = server.Config.TLSConfig
|
||||
|
||||
server.StartTLS()
|
||||
|
||||
return &http.Client{
|
||||
Transport: clientTrans,
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+101
@@ -0,0 +1,101 @@
|
||||
package eventstreamtest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi"
|
||||
)
|
||||
|
||||
// ServeEventStream provides serving EventStream messages from a HTTP server to
|
||||
// the client. The events are sent sequentially to the client without delay.
|
||||
type ServeEventStream struct {
|
||||
T *testing.T
|
||||
Events []eventstream.Message
|
||||
}
|
||||
|
||||
func (s ServeEventStream) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
encoder := eventstream.NewEncoder(flushWriter{w})
|
||||
|
||||
for _, event := range s.Events {
|
||||
encoder.Encode(event)
|
||||
}
|
||||
}
|
||||
|
||||
// SetupEventStreamSession creates a HTTP server SDK session for communicating
|
||||
// with that server to be used for EventStream APIs. If HTTP/2 is enabled the
|
||||
// server/client will only attempt to use HTTP/2.
|
||||
func SetupEventStreamSession(
|
||||
t *testing.T, handler http.Handler, h2 bool,
|
||||
) (sess *session.Session, cleanupFn func(), err error) {
|
||||
server := httptest.NewUnstartedServer(handler)
|
||||
|
||||
client := setupServer(server, h2)
|
||||
|
||||
cleanupFn = func() {
|
||||
server.Close()
|
||||
}
|
||||
|
||||
sess, err = session.NewSession(unit.Session.Config, &aws.Config{
|
||||
Endpoint: &server.URL,
|
||||
DisableParamValidation: aws.Bool(true),
|
||||
HTTPClient: client,
|
||||
// LogLevel: aws.LogLevel(aws.LogDebugWithEventStreamBody),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return sess, cleanupFn, nil
|
||||
}
|
||||
|
||||
type flushWriter struct {
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
func (fw flushWriter) Write(p []byte) (n int, err error) {
|
||||
n, err = fw.w.Write(p)
|
||||
if f, ok := fw.w.(http.Flusher); ok {
|
||||
f.Flush()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// MarshalEventPayload marshals a SDK API shape into its associated wire
|
||||
// protocol payload.
|
||||
func MarshalEventPayload(
|
||||
payloadMarshaler protocol.PayloadMarshaler,
|
||||
v interface{},
|
||||
) []byte {
|
||||
var w bytes.Buffer
|
||||
err := payloadMarshaler.MarshalPayload(&w, v)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to marshal event %T, %v", v, v))
|
||||
}
|
||||
|
||||
return w.Bytes()
|
||||
}
|
||||
|
||||
// EventMessageTypeHeader is an event message type header for specifying an
|
||||
// event is an message type.
|
||||
var EventMessageTypeHeader = eventstream.Header{
|
||||
Name: eventstreamapi.MessageTypeHeader,
|
||||
Value: eventstream.StringValue(eventstreamapi.EventMessageType),
|
||||
}
|
||||
|
||||
// EventExceptionTypeHeader is an event exception type header for specifying an
|
||||
// event is an exeption type.
|
||||
var EventExceptionTypeHeader = eventstream.Header{
|
||||
Name: eventstreamapi.MessageTypeHeader,
|
||||
Value: eventstream.StringValue(eventstreamapi.ExceptionMessageType),
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Headers are a collection of EventStream header values.
|
||||
type Headers []Header
|
||||
|
||||
// Header is a single EventStream Key Value header pair.
|
||||
type Header struct {
|
||||
Name string
|
||||
Value Value
|
||||
}
|
||||
|
||||
// Set associates the name with a value. If the header name already exists in
|
||||
// the Headers the value will be replaced with the new one.
|
||||
func (hs *Headers) Set(name string, value Value) {
|
||||
var i int
|
||||
for ; i < len(*hs); i++ {
|
||||
if (*hs)[i].Name == name {
|
||||
(*hs)[i].Value = value
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
*hs = append(*hs, Header{
|
||||
Name: name, Value: value,
|
||||
})
|
||||
}
|
||||
|
||||
// Get returns the Value associated with the header. Nil is returned if the
|
||||
// value does not exist.
|
||||
func (hs Headers) Get(name string) Value {
|
||||
for i := 0; i < len(hs); i++ {
|
||||
if h := hs[i]; h.Name == name {
|
||||
return h.Value
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Del deletes the value in the Headers if it exists.
|
||||
func (hs *Headers) Del(name string) {
|
||||
for i := 0; i < len(*hs); i++ {
|
||||
if (*hs)[i].Name == name {
|
||||
copy((*hs)[i:], (*hs)[i+1:])
|
||||
(*hs) = (*hs)[:len(*hs)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func decodeHeaders(r io.Reader) (Headers, error) {
|
||||
hs := Headers{}
|
||||
|
||||
for {
|
||||
name, err := decodeHeaderName(r)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
// EOF while getting header name means no more headers
|
||||
break
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
value, err := decodeHeaderValue(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hs.Set(name, value)
|
||||
}
|
||||
|
||||
return hs, nil
|
||||
}
|
||||
|
||||
func decodeHeaderName(r io.Reader) (string, error) {
|
||||
var n headerName
|
||||
|
||||
var err error
|
||||
n.Len, err = decodeUint8(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
name := n.Name[:n.Len]
|
||||
if _, err := io.ReadFull(r, name); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(name), nil
|
||||
}
|
||||
|
||||
func decodeHeaderValue(r io.Reader) (Value, error) {
|
||||
var raw rawValue
|
||||
|
||||
typ, err := decodeUint8(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
raw.Type = valueType(typ)
|
||||
|
||||
var v Value
|
||||
|
||||
switch raw.Type {
|
||||
case trueValueType:
|
||||
v = BoolValue(true)
|
||||
case falseValueType:
|
||||
v = BoolValue(false)
|
||||
case int8ValueType:
|
||||
var tv Int8Value
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case int16ValueType:
|
||||
var tv Int16Value
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case int32ValueType:
|
||||
var tv Int32Value
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case int64ValueType:
|
||||
var tv Int64Value
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case bytesValueType:
|
||||
var tv BytesValue
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case stringValueType:
|
||||
var tv StringValue
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case timestampValueType:
|
||||
var tv TimestampValue
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
case uuidValueType:
|
||||
var tv UUIDValue
|
||||
err = tv.decode(r)
|
||||
v = tv
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown value type %d", raw.Type))
|
||||
}
|
||||
|
||||
// Error could be EOF, let caller deal with it
|
||||
return v, err
|
||||
}
|
||||
|
||||
const maxHeaderNameLen = 255
|
||||
|
||||
type headerName struct {
|
||||
Len uint8
|
||||
Name [maxHeaderNameLen]byte
|
||||
}
|
||||
|
||||
func (v headerName) encode(w io.Writer) error {
|
||||
if err := binary.Write(w, binary.BigEndian, v.Len); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := w.Write(v.Name[:v.Len])
|
||||
return err
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestHeaders_Set(t *testing.T) {
|
||||
expect := Headers{
|
||||
{Name: "ABC", Value: StringValue("123")},
|
||||
{Name: "EFG", Value: TimestampValue(time.Time{})},
|
||||
}
|
||||
|
||||
var actual Headers
|
||||
actual.Set("ABC", Int32Value(123))
|
||||
actual.Set("ABC", StringValue("123")) // replace case
|
||||
actual.Set("EFG", TimestampValue(time.Time{}))
|
||||
|
||||
if e, a := expect, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v headers, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeaders_Get(t *testing.T) {
|
||||
headers := Headers{
|
||||
{Name: "ABC", Value: StringValue("123")},
|
||||
{Name: "EFG", Value: TimestampValue(time.Time{})},
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
Name string
|
||||
Value Value
|
||||
}{
|
||||
{Name: "ABC", Value: StringValue("123")},
|
||||
{Name: "EFG", Value: TimestampValue(time.Time{})},
|
||||
{Name: "NotFound"},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
actual := headers.Get(c.Name)
|
||||
if e, a := c.Value, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %v value, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeaders_Del(t *testing.T) {
|
||||
headers := Headers{
|
||||
{Name: "ABC", Value: StringValue("123")},
|
||||
{Name: "EFG", Value: TimestampValue(time.Time{})},
|
||||
{Name: "HIJ", Value: StringValue("123")},
|
||||
{Name: "KML", Value: TimestampValue(time.Time{})},
|
||||
}
|
||||
expectAfterDel := Headers{
|
||||
{Name: "EFG", Value: TimestampValue(time.Time{})},
|
||||
}
|
||||
|
||||
headers.Del("HIJ")
|
||||
headers.Del("ABC")
|
||||
headers.Del("KML")
|
||||
|
||||
if e, a := expectAfterDel, headers; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expect %v headers, got %v", e, a)
|
||||
}
|
||||
}
|
||||
+501
@@ -0,0 +1,501 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const maxHeaderValueLen = 1<<15 - 1 // 2^15-1 or 32KB - 1
|
||||
|
||||
// valueType is the EventStream header value type.
|
||||
type valueType uint8
|
||||
|
||||
// Header value types
|
||||
const (
|
||||
trueValueType valueType = iota
|
||||
falseValueType
|
||||
int8ValueType // Byte
|
||||
int16ValueType // Short
|
||||
int32ValueType // Integer
|
||||
int64ValueType // Long
|
||||
bytesValueType
|
||||
stringValueType
|
||||
timestampValueType
|
||||
uuidValueType
|
||||
)
|
||||
|
||||
func (t valueType) String() string {
|
||||
switch t {
|
||||
case trueValueType:
|
||||
return "bool"
|
||||
case falseValueType:
|
||||
return "bool"
|
||||
case int8ValueType:
|
||||
return "int8"
|
||||
case int16ValueType:
|
||||
return "int16"
|
||||
case int32ValueType:
|
||||
return "int32"
|
||||
case int64ValueType:
|
||||
return "int64"
|
||||
case bytesValueType:
|
||||
return "byte_array"
|
||||
case stringValueType:
|
||||
return "string"
|
||||
case timestampValueType:
|
||||
return "timestamp"
|
||||
case uuidValueType:
|
||||
return "uuid"
|
||||
default:
|
||||
return fmt.Sprintf("unknown value type %d", uint8(t))
|
||||
}
|
||||
}
|
||||
|
||||
type rawValue struct {
|
||||
Type valueType
|
||||
Len uint16 // Only set for variable length slices
|
||||
Value []byte // byte representation of value, BigEndian encoding.
|
||||
}
|
||||
|
||||
func (r rawValue) encodeScalar(w io.Writer, v interface{}) error {
|
||||
return binaryWriteFields(w, binary.BigEndian,
|
||||
r.Type,
|
||||
v,
|
||||
)
|
||||
}
|
||||
|
||||
func (r rawValue) encodeFixedSlice(w io.Writer, v []byte) error {
|
||||
binary.Write(w, binary.BigEndian, r.Type)
|
||||
|
||||
_, err := w.Write(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r rawValue) encodeBytes(w io.Writer, v []byte) error {
|
||||
if len(v) > maxHeaderValueLen {
|
||||
return LengthError{
|
||||
Part: "header value",
|
||||
Want: maxHeaderValueLen, Have: len(v),
|
||||
Value: v,
|
||||
}
|
||||
}
|
||||
r.Len = uint16(len(v))
|
||||
|
||||
err := binaryWriteFields(w, binary.BigEndian,
|
||||
r.Type,
|
||||
r.Len,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = w.Write(v)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r rawValue) encodeString(w io.Writer, v string) error {
|
||||
if len(v) > maxHeaderValueLen {
|
||||
return LengthError{
|
||||
Part: "header value",
|
||||
Want: maxHeaderValueLen, Have: len(v),
|
||||
Value: v,
|
||||
}
|
||||
}
|
||||
r.Len = uint16(len(v))
|
||||
|
||||
type stringWriter interface {
|
||||
WriteString(string) (int, error)
|
||||
}
|
||||
|
||||
err := binaryWriteFields(w, binary.BigEndian,
|
||||
r.Type,
|
||||
r.Len,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if sw, ok := w.(stringWriter); ok {
|
||||
_, err = sw.WriteString(v)
|
||||
} else {
|
||||
_, err = w.Write([]byte(v))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func decodeFixedBytesValue(r io.Reader, buf []byte) error {
|
||||
_, err := io.ReadFull(r, buf)
|
||||
return err
|
||||
}
|
||||
|
||||
func decodeBytesValue(r io.Reader) ([]byte, error) {
|
||||
var raw rawValue
|
||||
var err error
|
||||
raw.Len, err = decodeUint16(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := make([]byte, raw.Len)
|
||||
_, err = io.ReadFull(r, buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func decodeStringValue(r io.Reader) (string, error) {
|
||||
v, err := decodeBytesValue(r)
|
||||
return string(v), err
|
||||
}
|
||||
|
||||
// Value represents the abstract header value.
|
||||
type Value interface {
|
||||
Get() interface{}
|
||||
String() string
|
||||
valueType() valueType
|
||||
encode(io.Writer) error
|
||||
}
|
||||
|
||||
// An BoolValue provides eventstream encoding, and representation
|
||||
// of a Go bool value.
|
||||
type BoolValue bool
|
||||
|
||||
// Get returns the underlying type
|
||||
func (v BoolValue) Get() interface{} {
|
||||
return bool(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (v BoolValue) valueType() valueType {
|
||||
if v {
|
||||
return trueValueType
|
||||
}
|
||||
return falseValueType
|
||||
}
|
||||
|
||||
func (v BoolValue) String() string {
|
||||
return strconv.FormatBool(bool(v))
|
||||
}
|
||||
|
||||
// encode encodes the BoolValue into an eventstream binary value
|
||||
// representation.
|
||||
func (v BoolValue) encode(w io.Writer) error {
|
||||
return binary.Write(w, binary.BigEndian, v.valueType())
|
||||
}
|
||||
|
||||
// An Int8Value provides eventstream encoding, and representation of a Go
|
||||
// int8 value.
|
||||
type Int8Value int8
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v Int8Value) Get() interface{} {
|
||||
return int8(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (Int8Value) valueType() valueType {
|
||||
return int8ValueType
|
||||
}
|
||||
|
||||
func (v Int8Value) String() string {
|
||||
return fmt.Sprintf("0x%02x", int8(v))
|
||||
}
|
||||
|
||||
// encode encodes the Int8Value into an eventstream binary value
|
||||
// representation.
|
||||
func (v Int8Value) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
|
||||
return raw.encodeScalar(w, v)
|
||||
}
|
||||
|
||||
func (v *Int8Value) decode(r io.Reader) error {
|
||||
n, err := decodeUint8(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = Int8Value(n)
|
||||
return nil
|
||||
}
|
||||
|
||||
// An Int16Value provides eventstream encoding, and representation of a Go
|
||||
// int16 value.
|
||||
type Int16Value int16
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v Int16Value) Get() interface{} {
|
||||
return int16(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (Int16Value) valueType() valueType {
|
||||
return int16ValueType
|
||||
}
|
||||
|
||||
func (v Int16Value) String() string {
|
||||
return fmt.Sprintf("0x%04x", int16(v))
|
||||
}
|
||||
|
||||
// encode encodes the Int16Value into an eventstream binary value
|
||||
// representation.
|
||||
func (v Int16Value) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
return raw.encodeScalar(w, v)
|
||||
}
|
||||
|
||||
func (v *Int16Value) decode(r io.Reader) error {
|
||||
n, err := decodeUint16(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = Int16Value(n)
|
||||
return nil
|
||||
}
|
||||
|
||||
// An Int32Value provides eventstream encoding, and representation of a Go
|
||||
// int32 value.
|
||||
type Int32Value int32
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v Int32Value) Get() interface{} {
|
||||
return int32(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (Int32Value) valueType() valueType {
|
||||
return int32ValueType
|
||||
}
|
||||
|
||||
func (v Int32Value) String() string {
|
||||
return fmt.Sprintf("0x%08x", int32(v))
|
||||
}
|
||||
|
||||
// encode encodes the Int32Value into an eventstream binary value
|
||||
// representation.
|
||||
func (v Int32Value) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
return raw.encodeScalar(w, v)
|
||||
}
|
||||
|
||||
func (v *Int32Value) decode(r io.Reader) error {
|
||||
n, err := decodeUint32(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = Int32Value(n)
|
||||
return nil
|
||||
}
|
||||
|
||||
// An Int64Value provides eventstream encoding, and representation of a Go
|
||||
// int64 value.
|
||||
type Int64Value int64
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v Int64Value) Get() interface{} {
|
||||
return int64(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (Int64Value) valueType() valueType {
|
||||
return int64ValueType
|
||||
}
|
||||
|
||||
func (v Int64Value) String() string {
|
||||
return fmt.Sprintf("0x%016x", int64(v))
|
||||
}
|
||||
|
||||
// encode encodes the Int64Value into an eventstream binary value
|
||||
// representation.
|
||||
func (v Int64Value) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
return raw.encodeScalar(w, v)
|
||||
}
|
||||
|
||||
func (v *Int64Value) decode(r io.Reader) error {
|
||||
n, err := decodeUint64(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = Int64Value(n)
|
||||
return nil
|
||||
}
|
||||
|
||||
// An BytesValue provides eventstream encoding, and representation of a Go
|
||||
// byte slice.
|
||||
type BytesValue []byte
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v BytesValue) Get() interface{} {
|
||||
return []byte(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (BytesValue) valueType() valueType {
|
||||
return bytesValueType
|
||||
}
|
||||
|
||||
func (v BytesValue) String() string {
|
||||
return base64.StdEncoding.EncodeToString([]byte(v))
|
||||
}
|
||||
|
||||
// encode encodes the BytesValue into an eventstream binary value
|
||||
// representation.
|
||||
func (v BytesValue) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
|
||||
return raw.encodeBytes(w, []byte(v))
|
||||
}
|
||||
|
||||
func (v *BytesValue) decode(r io.Reader) error {
|
||||
buf, err := decodeBytesValue(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = BytesValue(buf)
|
||||
return nil
|
||||
}
|
||||
|
||||
// An StringValue provides eventstream encoding, and representation of a Go
|
||||
// string.
|
||||
type StringValue string
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v StringValue) Get() interface{} {
|
||||
return string(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (StringValue) valueType() valueType {
|
||||
return stringValueType
|
||||
}
|
||||
|
||||
func (v StringValue) String() string {
|
||||
return string(v)
|
||||
}
|
||||
|
||||
// encode encodes the StringValue into an eventstream binary value
|
||||
// representation.
|
||||
func (v StringValue) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
|
||||
return raw.encodeString(w, string(v))
|
||||
}
|
||||
|
||||
func (v *StringValue) decode(r io.Reader) error {
|
||||
s, err := decodeStringValue(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = StringValue(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
// An TimestampValue provides eventstream encoding, and representation of a Go
|
||||
// timestamp.
|
||||
type TimestampValue time.Time
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v TimestampValue) Get() interface{} {
|
||||
return time.Time(v)
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (TimestampValue) valueType() valueType {
|
||||
return timestampValueType
|
||||
}
|
||||
|
||||
func (v TimestampValue) epochMilli() int64 {
|
||||
nano := time.Time(v).UnixNano()
|
||||
msec := nano / int64(time.Millisecond)
|
||||
return msec
|
||||
}
|
||||
|
||||
func (v TimestampValue) String() string {
|
||||
msec := v.epochMilli()
|
||||
return strconv.FormatInt(msec, 10)
|
||||
}
|
||||
|
||||
// encode encodes the TimestampValue into an eventstream binary value
|
||||
// representation.
|
||||
func (v TimestampValue) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
|
||||
msec := v.epochMilli()
|
||||
return raw.encodeScalar(w, msec)
|
||||
}
|
||||
|
||||
func (v *TimestampValue) decode(r io.Reader) error {
|
||||
n, err := decodeUint64(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*v = TimestampValue(timeFromEpochMilli(int64(n)))
|
||||
return nil
|
||||
}
|
||||
|
||||
func timeFromEpochMilli(t int64) time.Time {
|
||||
secs := t / 1e3
|
||||
msec := t % 1e3
|
||||
return time.Unix(secs, msec*int64(time.Millisecond)).UTC()
|
||||
}
|
||||
|
||||
// An UUIDValue provides eventstream encoding, and representation of a UUID
|
||||
// value.
|
||||
type UUIDValue [16]byte
|
||||
|
||||
// Get returns the underlying value.
|
||||
func (v UUIDValue) Get() interface{} {
|
||||
return v[:]
|
||||
}
|
||||
|
||||
// valueType returns the EventStream header value type value.
|
||||
func (UUIDValue) valueType() valueType {
|
||||
return uuidValueType
|
||||
}
|
||||
|
||||
func (v UUIDValue) String() string {
|
||||
return fmt.Sprintf(`%X-%X-%X-%X-%X`, v[0:4], v[4:6], v[6:8], v[8:10], v[10:])
|
||||
}
|
||||
|
||||
// encode encodes the UUIDValue into an eventstream binary value
|
||||
// representation.
|
||||
func (v UUIDValue) encode(w io.Writer) error {
|
||||
raw := rawValue{
|
||||
Type: v.valueType(),
|
||||
}
|
||||
|
||||
return raw.encodeFixedSlice(w, v[:])
|
||||
}
|
||||
|
||||
func (v *UUIDValue) decode(r io.Reader) error {
|
||||
tv := (*v)[:]
|
||||
return decodeFixedBytesValue(r, tv)
|
||||
}
|
||||
Generated
Vendored
+203
@@ -0,0 +1,203 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func binWrite(v interface{}) []byte {
|
||||
var w bytes.Buffer
|
||||
binary.Write(&w, binary.BigEndian, v)
|
||||
return w.Bytes()
|
||||
}
|
||||
|
||||
var testValueEncodingCases = []struct {
|
||||
Val Value
|
||||
Expect []byte
|
||||
Decode func(io.Reader) (Value, error)
|
||||
}{
|
||||
{
|
||||
BoolValue(true),
|
||||
[]byte{byte(trueValueType)},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
BoolValue(false),
|
||||
[]byte{byte(falseValueType)},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
Int8Value(0x0f),
|
||||
[]byte{byte(int8ValueType), 0x0f},
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v Int8Value
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
Int16Value(0x0f),
|
||||
append([]byte{byte(int16ValueType)}, binWrite(int16(0x0f))...),
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v Int16Value
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
Int32Value(0x0f),
|
||||
append([]byte{byte(int32ValueType)}, binWrite(int32(0x0f))...),
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v Int32Value
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
Int64Value(0x0f),
|
||||
append([]byte{byte(int64ValueType)}, binWrite(int64(0x0f))...),
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v Int64Value
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
BytesValue([]byte{0, 1, 2, 3}),
|
||||
[]byte{byte(bytesValueType), 0x00, 0x04, 0, 1, 2, 3},
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v BytesValue
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
StringValue("abc123"),
|
||||
append([]byte{byte(stringValueType), 0, 6}, []byte("abc123")...),
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v StringValue
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
TimestampValue(
|
||||
time.Date(2014, 04, 04, 0, 1, 0, 0, time.FixedZone("PDT", -7)),
|
||||
),
|
||||
append([]byte{byte(timestampValueType)}, binWrite(int64(1396569667000))...),
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v TimestampValue
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
{
|
||||
UUIDValue(
|
||||
[16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf},
|
||||
),
|
||||
[]byte{byte(uuidValueType), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf},
|
||||
func(r io.Reader) (Value, error) {
|
||||
var v UUIDValue
|
||||
err := v.decode(r)
|
||||
return v, err
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestValue_MarshalValue(t *testing.T) {
|
||||
for i, c := range testValueEncodingCases {
|
||||
var w bytes.Buffer
|
||||
|
||||
if err := c.Val.encode(&w); err != nil {
|
||||
t.Fatalf("%d, expect no error, got %v", i, err)
|
||||
}
|
||||
|
||||
if e, a := c.Expect, w.Bytes(); !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeader_DecodeValues(t *testing.T) {
|
||||
for i, c := range testValueEncodingCases {
|
||||
r := bytes.NewBuffer(c.Expect)
|
||||
v, err := decodeHeaderValue(r)
|
||||
if err != nil {
|
||||
t.Fatalf("%d, expect no error, got %v", i, err)
|
||||
}
|
||||
|
||||
switch tv := v.(type) {
|
||||
case TimestampValue:
|
||||
exp := time.Time(c.Val.(TimestampValue))
|
||||
if e, a := exp, time.Time(tv); !e.Equal(a) {
|
||||
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
default:
|
||||
if e, a := c.Val, v; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValue_Decode(t *testing.T) {
|
||||
for i, c := range testValueEncodingCases {
|
||||
if c.Decode == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
r := bytes.NewBuffer(c.Expect)
|
||||
r.ReadByte() // strip off Type field
|
||||
|
||||
v, err := c.Decode(r)
|
||||
if err != nil {
|
||||
t.Fatalf("%d, expect no error, got %v", i, err)
|
||||
}
|
||||
|
||||
switch tv := v.(type) {
|
||||
case TimestampValue:
|
||||
exp := time.Time(c.Val.(TimestampValue))
|
||||
if e, a := exp, time.Time(tv); !e.Equal(a) {
|
||||
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
default:
|
||||
if e, a := c.Val, v; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValue_String(t *testing.T) {
|
||||
cases := []struct {
|
||||
Val Value
|
||||
Expect string
|
||||
}{
|
||||
{BoolValue(true), "true"},
|
||||
{BoolValue(false), "false"},
|
||||
{Int8Value(0x0f), "0x0f"},
|
||||
{Int16Value(0x0f), "0x000f"},
|
||||
{Int32Value(0x0f), "0x0000000f"},
|
||||
{Int64Value(0x0f), "0x000000000000000f"},
|
||||
{BytesValue([]byte{0, 1, 2, 3}), "AAECAw=="},
|
||||
{StringValue("abc123"), "abc123"},
|
||||
{TimestampValue(
|
||||
time.Date(2014, 04, 04, 0, 1, 0, 0, time.FixedZone("PDT", -7)),
|
||||
),
|
||||
"1396569667000",
|
||||
},
|
||||
{UUIDValue([16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}),
|
||||
"00010203-0405-0607-0809-0A0B0C0D0E0F",
|
||||
},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
if e, a := c.Expect, c.Val.String(); e != a {
|
||||
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"hash/crc32"
|
||||
)
|
||||
|
||||
const preludeLen = 8
|
||||
const preludeCRCLen = 4
|
||||
const msgCRCLen = 4
|
||||
const minMsgLen = preludeLen + preludeCRCLen + msgCRCLen
|
||||
const maxPayloadLen = 1024 * 1024 * 16 // 16MB
|
||||
const maxHeadersLen = 1024 * 128 // 128KB
|
||||
const maxMsgLen = minMsgLen + maxHeadersLen + maxPayloadLen
|
||||
|
||||
var crc32IEEETable = crc32.MakeTable(crc32.IEEE)
|
||||
|
||||
// A Message provides the eventstream message representation.
|
||||
type Message struct {
|
||||
Headers Headers
|
||||
Payload []byte
|
||||
}
|
||||
|
||||
func (m *Message) rawMessage() (rawMessage, error) {
|
||||
var raw rawMessage
|
||||
|
||||
if len(m.Headers) > 0 {
|
||||
var headers bytes.Buffer
|
||||
if err := encodeHeaders(&headers, m.Headers); err != nil {
|
||||
return rawMessage{}, err
|
||||
}
|
||||
raw.Headers = headers.Bytes()
|
||||
raw.HeadersLen = uint32(len(raw.Headers))
|
||||
}
|
||||
|
||||
raw.Length = raw.HeadersLen + uint32(len(m.Payload)) + minMsgLen
|
||||
|
||||
hash := crc32.New(crc32IEEETable)
|
||||
binaryWriteFields(hash, binary.BigEndian, raw.Length, raw.HeadersLen)
|
||||
raw.PreludeCRC = hash.Sum32()
|
||||
|
||||
binaryWriteFields(hash, binary.BigEndian, raw.PreludeCRC)
|
||||
|
||||
if raw.HeadersLen > 0 {
|
||||
hash.Write(raw.Headers)
|
||||
}
|
||||
|
||||
// Read payload bytes and update hash for it as well.
|
||||
if len(m.Payload) > 0 {
|
||||
raw.Payload = m.Payload
|
||||
hash.Write(raw.Payload)
|
||||
}
|
||||
|
||||
raw.CRC = hash.Sum32()
|
||||
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
type messagePrelude struct {
|
||||
Length uint32
|
||||
HeadersLen uint32
|
||||
PreludeCRC uint32
|
||||
}
|
||||
|
||||
func (p messagePrelude) PayloadLen() uint32 {
|
||||
return p.Length - p.HeadersLen - minMsgLen
|
||||
}
|
||||
|
||||
func (p messagePrelude) ValidateLens() error {
|
||||
if p.Length == 0 || p.Length > maxMsgLen {
|
||||
return LengthError{
|
||||
Part: "message prelude",
|
||||
Want: maxMsgLen,
|
||||
Have: int(p.Length),
|
||||
}
|
||||
}
|
||||
if p.HeadersLen > maxHeadersLen {
|
||||
return LengthError{
|
||||
Part: "message headers",
|
||||
Want: maxHeadersLen,
|
||||
Have: int(p.HeadersLen),
|
||||
}
|
||||
}
|
||||
if payloadLen := p.PayloadLen(); payloadLen > maxPayloadLen {
|
||||
return LengthError{
|
||||
Part: "message payload",
|
||||
Want: maxPayloadLen,
|
||||
Have: int(payloadLen),
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type rawMessage struct {
|
||||
messagePrelude
|
||||
|
||||
Headers []byte
|
||||
Payload []byte
|
||||
|
||||
CRC uint32
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
package eventstream
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testCase struct {
|
||||
Name string
|
||||
Encoded []byte
|
||||
Decoded decodedMessage
|
||||
}
|
||||
|
||||
type testErrorCase struct {
|
||||
Name string
|
||||
Encoded []byte
|
||||
Err string
|
||||
}
|
||||
|
||||
type rawTestCase struct {
|
||||
Name string
|
||||
Encoded, Decoded []byte
|
||||
}
|
||||
|
||||
func readRawTestCases(root, class string) (map[string]rawTestCase, error) {
|
||||
encoded, err := readTests(filepath.Join(root, "encoded", class))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
decoded, err := readTests(filepath.Join(root, "decoded", class))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(encoded) == 0 {
|
||||
return nil, fmt.Errorf("expect encoded cases, found none")
|
||||
}
|
||||
|
||||
if len(encoded) != len(decoded) {
|
||||
return nil, fmt.Errorf("encoded and decoded sets different")
|
||||
}
|
||||
|
||||
rawCases := map[string]rawTestCase{}
|
||||
for name, encData := range encoded {
|
||||
decData, ok := decoded[name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("encoded %q case not found in decoded set", name)
|
||||
}
|
||||
|
||||
rawCases[name] = rawTestCase{
|
||||
Name: name,
|
||||
Encoded: encData,
|
||||
Decoded: decData,
|
||||
}
|
||||
}
|
||||
|
||||
return rawCases, nil
|
||||
}
|
||||
|
||||
func readNegativeTests(root string) ([]testErrorCase, error) {
|
||||
rawCases, err := readRawTestCases(root, "negative")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cases := make([]testErrorCase, 0, len(rawCases))
|
||||
for name, rawCase := range rawCases {
|
||||
cases = append(cases, testErrorCase{
|
||||
Name: name,
|
||||
Encoded: rawCase.Encoded,
|
||||
Err: string(rawCase.Decoded),
|
||||
})
|
||||
}
|
||||
|
||||
return cases, nil
|
||||
}
|
||||
|
||||
func readPositiveTests(root string) ([]testCase, error) {
|
||||
rawCases, err := readRawTestCases(root, "positive")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cases := make([]testCase, 0, len(rawCases))
|
||||
for name, rawCase := range rawCases {
|
||||
|
||||
var dec decodedMessage
|
||||
if err := json.Unmarshal(rawCase.Decoded, &dec); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode %q, %v", name, err)
|
||||
}
|
||||
|
||||
cases = append(cases, testCase{
|
||||
Name: name,
|
||||
Encoded: rawCase.Encoded,
|
||||
Decoded: dec,
|
||||
})
|
||||
}
|
||||
|
||||
return cases, nil
|
||||
}
|
||||
|
||||
func readTests(root string) (map[string][]byte, error) {
|
||||
items, err := ioutil.ReadDir(root)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read test suite %q dirs, %v", root, err)
|
||||
}
|
||||
|
||||
cases := map[string][]byte{}
|
||||
for _, item := range items {
|
||||
if item.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
filename := filepath.Join(root, item.Name())
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read test_data file %q, %v", filename, err)
|
||||
}
|
||||
|
||||
cases[item.Name()] = data
|
||||
}
|
||||
|
||||
return cases, nil
|
||||
}
|
||||
|
||||
func compareLines(t *testing.T, a, b []byte) bool {
|
||||
as := bufio.NewScanner(bytes.NewBuffer(a))
|
||||
bs := bufio.NewScanner(bytes.NewBuffer(b))
|
||||
|
||||
var failed bool
|
||||
for {
|
||||
if ab, bb := as.Scan(), bs.Scan(); ab != bb {
|
||||
t.Errorf("expect a & b to have same number of lines")
|
||||
return false
|
||||
} else if !ab {
|
||||
break
|
||||
}
|
||||
|
||||
if v1, v2 := as.Text(), bs.Text(); v1 != v2 {
|
||||
t.Errorf("expect %q to be %q", v1, v2)
|
||||
failed = true
|
||||
}
|
||||
}
|
||||
|
||||
return !failed
|
||||
}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
Prelude checksum mismatch
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
Message checksum mismatch
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
Prelude checksum mismatch
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
Message checksum mismatch
|
||||
Generated
Vendored
+58
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"total_length": 204,
|
||||
"headers_length": 175,
|
||||
"prelude_crc": 263087306,
|
||||
"headers": [ {
|
||||
"name": "event-type",
|
||||
"type": 4,
|
||||
"value": 40972
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"type": 7,
|
||||
"value": "YXBwbGljYXRpb24vanNvbg=="
|
||||
},
|
||||
{
|
||||
"name": "bool false",
|
||||
"type": 1,
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"name": "bool true",
|
||||
"type": 0,
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"name": "byte",
|
||||
"type": 2,
|
||||
"value": -49
|
||||
},
|
||||
{
|
||||
"name": "byte buf",
|
||||
"type": 6,
|
||||
"value": "SSdtIGEgbGl0dGxlIHRlYXBvdCE="
|
||||
},
|
||||
{
|
||||
"name": "timestamp",
|
||||
"type": 8,
|
||||
"value": 8675309
|
||||
},
|
||||
{
|
||||
"name": "int16",
|
||||
"type": 3,
|
||||
"value": 42
|
||||
},
|
||||
{
|
||||
"name": "int64",
|
||||
"type": 5,
|
||||
"value": 42424242
|
||||
},
|
||||
{
|
||||
"name": "uuid",
|
||||
"type": 9,
|
||||
"value": "AQIDBAUGBwgJCgsMDQ4PEA=="
|
||||
}
|
||||
],
|
||||
"payload": "eydmb28nOidiYXInfQ==",
|
||||
"message_crc": -1415188212
|
||||
}
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"total_length": 16,
|
||||
"headers_length": 0,
|
||||
"prelude_crc": 96618731,
|
||||
"headers": [ ],
|
||||
"payload": "",
|
||||
"message_crc": 2107164927
|
||||
}
|
||||
vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/testdata/decoded/positive/int32_header
Generated
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"total_length": 45,
|
||||
"headers_length": 16,
|
||||
"prelude_crc": 1103373496,
|
||||
"headers": [ {
|
||||
"name": "event-type",
|
||||
"type": 4,
|
||||
"value": 40972
|
||||
}
|
||||
],
|
||||
"payload": "eydmb28nOidiYXInfQ==",
|
||||
"message_crc": 921993376
|
||||
}
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"total_length": 29,
|
||||
"headers_length": 0,
|
||||
"prelude_crc": -44921766,
|
||||
"headers": [ ],
|
||||
"payload": "eydmb28nOidiYXInfQ==",
|
||||
"message_crc": -1016776394
|
||||
}
|
||||
Generated
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"total_length": 61,
|
||||
"headers_length": 32,
|
||||
"prelude_crc": 134054806,
|
||||
"headers": [ {
|
||||
"name": "content-type",
|
||||
"type": 7,
|
||||
"value": "YXBwbGljYXRpb24vanNvbg=="
|
||||
}
|
||||
],
|
||||
"payload": "eydmb28nOidiYXInfQ==",
|
||||
"message_crc": -1919153999
|
||||
}
|
||||
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/testdata/encoded/positive/int32_header
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
+68
@@ -0,0 +1,68 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// ValidateEndpointHostHandler is a request handler that will validate the
|
||||
// request endpoint's hosts is a valid RFC 3986 host.
|
||||
var ValidateEndpointHostHandler = request.NamedHandler{
|
||||
Name: "awssdk.protocol.ValidateEndpointHostHandler",
|
||||
Fn: func(r *request.Request) {
|
||||
err := ValidateEndpointHost(r.Operation.Name, r.HTTPRequest.URL.Host)
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// ValidateEndpointHost validates that the host string passed in is a valid RFC
|
||||
// 3986 host. Returns error if the host is not valid.
|
||||
func ValidateEndpointHost(opName, host string) error {
|
||||
paramErrs := request.ErrInvalidParams{Context: opName}
|
||||
labels := strings.Split(host, ".")
|
||||
|
||||
for i, label := range labels {
|
||||
if i == len(labels)-1 && len(label) == 0 {
|
||||
// Allow trailing dot for FQDN hosts.
|
||||
continue
|
||||
}
|
||||
|
||||
if !ValidHostLabel(label) {
|
||||
paramErrs.Add(request.NewErrParamFormat(
|
||||
"endpoint host label", "[a-zA-Z0-9-]{1,63}", label))
|
||||
}
|
||||
}
|
||||
|
||||
if len(host) > 255 {
|
||||
paramErrs.Add(request.NewErrParamMaxLen(
|
||||
"endpoint host", 255, host,
|
||||
))
|
||||
}
|
||||
|
||||
if paramErrs.Len() > 0 {
|
||||
return paramErrs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidHostLabel returns if the label is a valid RFC 3986 host label.
|
||||
func ValidHostLabel(label string) bool {
|
||||
if l := len(label); l == 0 || l > 63 {
|
||||
return false
|
||||
}
|
||||
for _, r := range label {
|
||||
switch {
|
||||
case r >= '0' && r <= '9':
|
||||
case r >= 'A' && r <= 'Z':
|
||||
case r >= 'a' && r <= 'z':
|
||||
case r == '-':
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// HostPrefixHandlerName is the handler name for the host prefix request
|
||||
// handler.
|
||||
const HostPrefixHandlerName = "awssdk.endpoint.HostPrefixHandler"
|
||||
|
||||
// NewHostPrefixHandler constructs a build handler
|
||||
func NewHostPrefixHandler(prefix string, labelsFn func() map[string]string) request.NamedHandler {
|
||||
builder := HostPrefixBuilder{
|
||||
Prefix: prefix,
|
||||
LabelsFn: labelsFn,
|
||||
}
|
||||
|
||||
return request.NamedHandler{
|
||||
Name: HostPrefixHandlerName,
|
||||
Fn: builder.Build,
|
||||
}
|
||||
}
|
||||
|
||||
// HostPrefixBuilder provides the request handler to expand and prepend
|
||||
// the host prefix into the operation's request endpoint host.
|
||||
type HostPrefixBuilder struct {
|
||||
Prefix string
|
||||
LabelsFn func() map[string]string
|
||||
}
|
||||
|
||||
// Build updates the passed in Request with the HostPrefix template expanded.
|
||||
func (h HostPrefixBuilder) Build(r *request.Request) {
|
||||
if aws.BoolValue(r.Config.DisableEndpointHostPrefix) {
|
||||
return
|
||||
}
|
||||
|
||||
var labels map[string]string
|
||||
if h.LabelsFn != nil {
|
||||
labels = h.LabelsFn()
|
||||
}
|
||||
|
||||
prefix := h.Prefix
|
||||
for name, value := range labels {
|
||||
prefix = strings.Replace(prefix, "{"+name+"}", value, -1)
|
||||
}
|
||||
|
||||
r.HTTPRequest.URL.Host = prefix + r.HTTPRequest.URL.Host
|
||||
if len(r.HTTPRequest.Host) > 0 {
|
||||
r.HTTPRequest.Host = prefix + r.HTTPRequest.Host
|
||||
}
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
// +build go1.7
|
||||
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
func TestHostPrefixBuilder(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
URLHost string
|
||||
ReqHost string
|
||||
Prefix string
|
||||
LabelsFn func() map[string]string
|
||||
Disabled bool
|
||||
|
||||
ExpectURLHost string
|
||||
ExpectReqHost string
|
||||
}{
|
||||
"no labels": {
|
||||
URLHost: "service.region.amazonaws.com",
|
||||
Prefix: "data-",
|
||||
ExpectURLHost: "data-service.region.amazonaws.com",
|
||||
},
|
||||
"with labels": {
|
||||
URLHost: "service.region.amazonaws.com",
|
||||
Prefix: "{first}-{second}.",
|
||||
LabelsFn: func() map[string]string {
|
||||
return map[string]string{
|
||||
"first": "abc",
|
||||
"second": "123",
|
||||
}
|
||||
},
|
||||
ExpectURLHost: "abc-123.service.region.amazonaws.com",
|
||||
},
|
||||
"with host prefix disabled": {
|
||||
Disabled: true,
|
||||
URLHost: "service.region.amazonaws.com",
|
||||
Prefix: "{first}-{second}.",
|
||||
LabelsFn: func() map[string]string {
|
||||
return map[string]string{
|
||||
"first": "abc",
|
||||
"second": "123",
|
||||
}
|
||||
},
|
||||
ExpectURLHost: "service.region.amazonaws.com",
|
||||
},
|
||||
"with duplicate labels": {
|
||||
URLHost: "service.region.amazonaws.com",
|
||||
Prefix: "{first}-{second}-{first}.",
|
||||
LabelsFn: func() map[string]string {
|
||||
return map[string]string{
|
||||
"first": "abc",
|
||||
"second": "123",
|
||||
}
|
||||
},
|
||||
ExpectURLHost: "abc-123-abc.service.region.amazonaws.com",
|
||||
},
|
||||
"with unbracketed labels": {
|
||||
URLHost: "service.region.amazonaws.com",
|
||||
Prefix: "first-{second}.",
|
||||
LabelsFn: func() map[string]string {
|
||||
return map[string]string{
|
||||
"first": "abc",
|
||||
"second": "123",
|
||||
}
|
||||
},
|
||||
ExpectURLHost: "first-123.service.region.amazonaws.com",
|
||||
},
|
||||
"with req host": {
|
||||
URLHost: "service.region.amazonaws.com:1234",
|
||||
ReqHost: "service.region.amazonaws.com",
|
||||
Prefix: "data-",
|
||||
ExpectURLHost: "data-service.region.amazonaws.com:1234",
|
||||
ExpectReqHost: "data-service.region.amazonaws.com",
|
||||
},
|
||||
}
|
||||
|
||||
for name, c := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
builder := HostPrefixBuilder{
|
||||
Prefix: c.Prefix, LabelsFn: c.LabelsFn,
|
||||
}
|
||||
req := &request.Request{
|
||||
Config: aws.Config{
|
||||
DisableEndpointHostPrefix: aws.Bool(c.Disabled),
|
||||
},
|
||||
HTTPRequest: &http.Request{
|
||||
Host: c.ReqHost,
|
||||
URL: &url.URL{
|
||||
Host: c.URLHost,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
builder.Build(req)
|
||||
if e, a := c.ExpectURLHost, req.HTTPRequest.URL.Host; e != a {
|
||||
t.Errorf("expect URL host %v, got %v", e, a)
|
||||
}
|
||||
if e, a := c.ExpectReqHost, req.HTTPRequest.Host; e != a {
|
||||
t.Errorf("expect request host %v, got %v", e, a)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
// +build go1.7
|
||||
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestValidHostLabel(t *testing.T) {
|
||||
cases := []struct {
|
||||
Input string
|
||||
Valid bool
|
||||
}{
|
||||
{Input: "abc123", Valid: true},
|
||||
{Input: "123", Valid: true},
|
||||
{Input: "abc", Valid: true},
|
||||
{Input: "123-abc", Valid: true},
|
||||
{Input: "{thing}-abc", Valid: false},
|
||||
{Input: "abc.123", Valid: false},
|
||||
{Input: "abc/123", Valid: false},
|
||||
{Input: "012345678901234567890123456789012345678901234567890123456789123", Valid: true},
|
||||
{Input: "0123456789012345678901234567890123456789012345678901234567891234", Valid: false},
|
||||
{Input: "", Valid: false},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
valid := ValidHostLabel(c.Input)
|
||||
if e, a := c.Valid, valid; e != a {
|
||||
t.Errorf("expect valid %v, got %v", e, a)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateEndpointHostHandler(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Input string
|
||||
Valid bool
|
||||
}{
|
||||
"valid host": {Input: "abc.123", Valid: true},
|
||||
"fqdn host": {Input: "abc.123.", Valid: true},
|
||||
"empty label": {Input: "abc..", Valid: false},
|
||||
"max host len": {
|
||||
Input: "123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.12345",
|
||||
Valid: true,
|
||||
},
|
||||
"too long host": {
|
||||
Input: "123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456",
|
||||
Valid: false,
|
||||
},
|
||||
}
|
||||
|
||||
for name, c := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
err := ValidateEndpointHost("OpName", c.Input)
|
||||
if e, a := c.Valid, err == nil; e != a {
|
||||
t.Errorf("expect valid %v, got %v, %v", e, a, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+12
-5
@@ -5,7 +5,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCanSetIdempotencyToken(t *testing.T) {
|
||||
@@ -55,7 +54,9 @@ func TestCanSetIdempotencyToken(t *testing.T) {
|
||||
v := reflect.Indirect(reflect.ValueOf(c.Case))
|
||||
ty := v.Type()
|
||||
canSet := protocol.CanSetIdempotencyToken(v.Field(0), ty.Field(0))
|
||||
assert.Equal(t, c.CanSet, canSet, "Expect case %d can set to match", i)
|
||||
if e, a := c.CanSet, canSet; e != a {
|
||||
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,18 +90,24 @@ func TestSetIdempotencyToken(t *testing.T) {
|
||||
v := reflect.Indirect(reflect.ValueOf(c.Case))
|
||||
|
||||
protocol.SetIdempotencyToken(v.Field(0))
|
||||
assert.NotEmpty(t, v.Field(0).Interface(), "Expect case %d to be set", i)
|
||||
if v.Field(0).Interface() == nil {
|
||||
t.Errorf("%d, expect not nil", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUUIDVersion4(t *testing.T) {
|
||||
uuid := protocol.UUIDVersion4(make([]byte, 16))
|
||||
assert.Equal(t, `00000000-0000-4000-8000-000000000000`, uuid)
|
||||
if e, a := `00000000-0000-4000-8000-000000000000`, uuid; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
|
||||
b := make([]byte, 16)
|
||||
for i := 0; i < len(b); i++ {
|
||||
b[i] = 1
|
||||
}
|
||||
uuid = protocol.UUIDVersion4(b)
|
||||
assert.Equal(t, `01010101-0101-4101-8101-010101010101`, uuid)
|
||||
if e, a := `01010101-0101-4101-8101-010101010101`, uuid; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
+11
-1
@@ -216,7 +216,17 @@ func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) erro
|
||||
default:
|
||||
switch converted := value.Interface().(type) {
|
||||
case time.Time:
|
||||
buf.Write(strconv.AppendInt(scratch[:0], converted.UTC().Unix(), 10))
|
||||
format := tag.Get("timestampFormat")
|
||||
if len(format) == 0 {
|
||||
format = protocol.UnixTimeFormatName
|
||||
}
|
||||
|
||||
ts := protocol.FormatTime(format, converted)
|
||||
if format != protocol.UnixTimeFormatName {
|
||||
ts = `"` + ts + `"`
|
||||
}
|
||||
|
||||
buf.WriteString(ts)
|
||||
case []byte:
|
||||
if !value.IsNil() {
|
||||
buf.WriteByte('"')
|
||||
|
||||
+13
-5
@@ -2,11 +2,11 @@ package jsonutil_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func S(s string) *string {
|
||||
@@ -83,11 +83,19 @@ func TestBuildJSON(t *testing.T) {
|
||||
for _, test := range jsonTests {
|
||||
out, err := jsonutil.BuildJSON(test.in)
|
||||
if test.err != "" {
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), test.err)
|
||||
if err == nil {
|
||||
t.Errorf("expect error")
|
||||
}
|
||||
if e, a := test.err, err.Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("expect %v, to contain %v", e, a)
|
||||
}
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, string(out), test.out)
|
||||
if err != nil {
|
||||
t.Errorf("expect nil, %v", err)
|
||||
}
|
||||
if e, a := string(out), test.out; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+40
-16
@@ -1,32 +1,47 @@
|
||||
package jsonutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
)
|
||||
|
||||
// UnmarshalJSONError unmarshal's the reader's JSON document into the passed in
|
||||
// type. The value to unmarshal the json document into must be a pointer to the
|
||||
// type.
|
||||
func UnmarshalJSONError(v interface{}, stream io.Reader) error {
|
||||
var errBuf bytes.Buffer
|
||||
body := io.TeeReader(stream, &errBuf)
|
||||
|
||||
err := json.NewDecoder(body).Decode(v)
|
||||
if err != nil {
|
||||
msg := "failed decoding error message"
|
||||
if err == io.EOF {
|
||||
msg = "error message missing"
|
||||
err = nil
|
||||
}
|
||||
return awserr.NewUnmarshalError(err, msg, errBuf.Bytes())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
err := json.NewDecoder(stream).Decode(&out)
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(b, &out); err != nil {
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -172,9 +187,6 @@ func unmarshalMap(value reflect.Value, data interface{}, tag reflect.StructTag)
|
||||
}
|
||||
|
||||
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:
|
||||
@@ -189,6 +201,17 @@ func unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTa
|
||||
return err
|
||||
}
|
||||
value.Set(reflect.ValueOf(b))
|
||||
case *time.Time:
|
||||
format := tag.Get("timestampFormat")
|
||||
if len(format) == 0 {
|
||||
format = protocol.ISO8601TimeFormatName
|
||||
}
|
||||
|
||||
t, err := protocol.ParseTime(format, d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
value.Set(reflect.ValueOf(&t))
|
||||
case aws.JSONValue:
|
||||
// No need to use escaping as the value is a non-quoted string.
|
||||
v, err := protocol.DecodeJSONValue(d, protocol.NoEscape)
|
||||
@@ -197,7 +220,7 @@ func unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTa
|
||||
}
|
||||
value.Set(reflect.ValueOf(v))
|
||||
default:
|
||||
return errf()
|
||||
return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type())
|
||||
}
|
||||
case float64:
|
||||
switch value.Interface().(type) {
|
||||
@@ -207,17 +230,18 @@ func unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTa
|
||||
case *float64:
|
||||
value.Set(reflect.ValueOf(&d))
|
||||
case *time.Time:
|
||||
// Time unmarshaled from a float64 can only be epoch seconds
|
||||
t := time.Unix(int64(d), 0).UTC()
|
||||
value.Set(reflect.ValueOf(&t))
|
||||
default:
|
||||
return errf()
|
||||
return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type())
|
||||
}
|
||||
case bool:
|
||||
switch value.Interface().(type) {
|
||||
case *bool:
|
||||
value.Set(reflect.ValueOf(&d))
|
||||
default:
|
||||
return errf()
|
||||
return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type())
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unsupported JSON value (%v)", data)
|
||||
|
||||
+605
-153
File diff suppressed because it is too large
Load Diff
+20
-21
@@ -6,8 +6,6 @@ package jsonrpc
|
||||
//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/json.json unmarshal_test.go
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
@@ -37,7 +35,7 @@ func Build(req *request.Request) {
|
||||
if req.ParamsFilled() {
|
||||
buf, err = jsonutil.BuildJSON(req.Params)
|
||||
if err != nil {
|
||||
req.Error = awserr.New("SerializationError", "failed encoding JSON RPC request", err)
|
||||
req.Error = awserr.New(request.ErrCodeSerialization, "failed encoding JSON RPC request", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
@@ -52,9 +50,12 @@ func Build(req *request.Request) {
|
||||
target := req.ClientInfo.TargetPrefix + "." + req.Operation.Name
|
||||
req.HTTPRequest.Header.Add("X-Amz-Target", target)
|
||||
}
|
||||
if req.ClientInfo.JSONVersion != "" {
|
||||
|
||||
// Only set the content type if one is not already specified and an
|
||||
// JSONVersion is specified.
|
||||
if ct, v := req.HTTPRequest.Header.Get("Content-Type"), req.ClientInfo.JSONVersion; len(ct) == 0 && len(v) != 0 {
|
||||
jsonVersion := req.ClientInfo.JSONVersion
|
||||
req.HTTPRequest.Header.Add("Content-Type", "application/x-amz-json-"+jsonVersion)
|
||||
req.HTTPRequest.Header.Set("Content-Type", "application/x-amz-json-"+jsonVersion)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +65,11 @@ func Unmarshal(req *request.Request) {
|
||||
if req.DataFilled() {
|
||||
err := jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
req.Error = awserr.New("SerializationError", "failed decoding JSON RPC response", err)
|
||||
req.Error = awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization, "failed decoding JSON RPC response", err),
|
||||
req.HTTPResponse.StatusCode,
|
||||
req.RequestID,
|
||||
)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -78,22 +83,16 @@ func UnmarshalMeta(req *request.Request) {
|
||||
// UnmarshalError unmarshals an error response for a JSON RPC service.
|
||||
func UnmarshalError(req *request.Request) {
|
||||
defer req.HTTPResponse.Body.Close()
|
||||
bodyBytes, err := ioutil.ReadAll(req.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
req.Error = awserr.New("SerializationError", "failed reading JSON RPC error response", err)
|
||||
return
|
||||
}
|
||||
if len(bodyBytes) == 0 {
|
||||
req.Error = awserr.NewRequestFailure(
|
||||
awserr.New("SerializationError", req.HTTPResponse.Status, nil),
|
||||
req.HTTPResponse.StatusCode,
|
||||
"",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
var jsonErr jsonErrorResponse
|
||||
if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil {
|
||||
req.Error = awserr.New("SerializationError", "failed decoding JSON RPC error response", err)
|
||||
err := jsonutil.UnmarshalJSONError(&jsonErr, req.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
req.Error = awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed to unmarshal error message", err),
|
||||
req.HTTPResponse.StatusCode,
|
||||
req.RequestID,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
// +build go1.8
|
||||
|
||||
package jsonrpc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
func TestUnmarshalError_SerializationError(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Request *request.Request
|
||||
ExpectMsg string
|
||||
ExpectBytes []byte
|
||||
}{
|
||||
"empty body": {
|
||||
Request: &request.Request{
|
||||
Data: &struct{}{},
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 400,
|
||||
Header: http.Header{
|
||||
"X-Amzn-Requestid": []string{"abc123"},
|
||||
},
|
||||
Body: ioutil.NopCloser(
|
||||
bytes.NewReader([]byte{}),
|
||||
),
|
||||
},
|
||||
},
|
||||
ExpectMsg: "error message missing",
|
||||
},
|
||||
"HTML body": {
|
||||
Request: &request.Request{
|
||||
Data: &struct{}{},
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 400,
|
||||
Header: http.Header{
|
||||
"X-Amzn-Requestid": []string{"abc123"},
|
||||
},
|
||||
Body: ioutil.NopCloser(
|
||||
bytes.NewReader([]byte(`<html></html>`)),
|
||||
),
|
||||
},
|
||||
},
|
||||
ExpectBytes: []byte(`<html></html>`),
|
||||
ExpectMsg: "failed decoding",
|
||||
},
|
||||
}
|
||||
|
||||
for name, c := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
req := c.Request
|
||||
|
||||
UnmarshalError(req)
|
||||
if req.Error == nil {
|
||||
t.Fatal("expect error, got none")
|
||||
}
|
||||
|
||||
aerr := req.Error.(awserr.RequestFailure)
|
||||
if e, a := request.ErrCodeSerialization, aerr.Code(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
|
||||
uerr := aerr.OrigErr().(awserr.UnmarshalError)
|
||||
if e, a := c.ExpectMsg, uerr.Message(); !strings.Contains(a, e) {
|
||||
t.Errorf("Expect %q, in %q", e, a)
|
||||
}
|
||||
if e, a := c.ExpectBytes, uerr.Bytes(); !bytes.Equal(e, a) {
|
||||
t.Errorf("expect:\n%v\nactual:\n%v", hex.Dump(e), hex.Dump(a))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+471
-43
@@ -75,7 +75,8 @@ func newOutputService1ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice1protocoltest",
|
||||
ServiceName: "OutputService1ProtocolTest",
|
||||
ServiceID: "OutputService1ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -108,7 +109,7 @@ const opOutputService1TestCaseOperation1 = "OperationName"
|
||||
// OutputService1TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService1TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -274,7 +275,8 @@ func newOutputService2ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice2protocoltest",
|
||||
ServiceName: "OutputService2ProtocolTest",
|
||||
ServiceID: "OutputService2ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -307,7 +309,7 @@ const opOutputService2TestCaseOperation1 = "OperationName"
|
||||
// OutputService2TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService2TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -439,7 +441,8 @@ func newOutputService3ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice3protocoltest",
|
||||
ServiceName: "OutputService3ProtocolTest",
|
||||
ServiceID: "OutputService3ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -472,7 +475,7 @@ const opOutputService3TestCaseOperation1 = "OperationName"
|
||||
// OutputService3TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService3TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -544,7 +547,11 @@ type OutputService3TestShapeOutputService3TestCaseOperation1Output struct {
|
||||
|
||||
StructMember *OutputService3TestShapeTimeContainer `type:"structure"`
|
||||
|
||||
TimeMember *time.Time `type:"timestamp" timestampFormat:"unix"`
|
||||
TimeArg *time.Time `type:"timestamp"`
|
||||
|
||||
TimeCustom *time.Time `type:"timestamp" timestampFormat:"rfc822"`
|
||||
|
||||
TimeFormat *time.Time `type:"timestamp" timestampFormat:"iso8601"`
|
||||
}
|
||||
|
||||
// SetStructMember sets the StructMember field's value.
|
||||
@@ -553,16 +560,36 @@ func (s *OutputService3TestShapeOutputService3TestCaseOperation1Output) SetStruc
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeMember sets the TimeMember field's value.
|
||||
func (s *OutputService3TestShapeOutputService3TestCaseOperation1Output) SetTimeMember(v time.Time) *OutputService3TestShapeOutputService3TestCaseOperation1Output {
|
||||
s.TimeMember = &v
|
||||
// SetTimeArg sets the TimeArg field's value.
|
||||
func (s *OutputService3TestShapeOutputService3TestCaseOperation1Output) SetTimeArg(v time.Time) *OutputService3TestShapeOutputService3TestCaseOperation1Output {
|
||||
s.TimeArg = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeCustom sets the TimeCustom field's value.
|
||||
func (s *OutputService3TestShapeOutputService3TestCaseOperation1Output) SetTimeCustom(v time.Time) *OutputService3TestShapeOutputService3TestCaseOperation1Output {
|
||||
s.TimeCustom = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeFormat sets the TimeFormat field's value.
|
||||
func (s *OutputService3TestShapeOutputService3TestCaseOperation1Output) SetTimeFormat(v time.Time) *OutputService3TestShapeOutputService3TestCaseOperation1Output {
|
||||
s.TimeFormat = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type OutputService3TestShapeTimeContainer struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
Foo *time.Time `locationName:"foo" type:"timestamp" timestampFormat:"unix"`
|
||||
Bar *time.Time `locationName:"bar" type:"timestamp" timestampFormat:"iso8601"`
|
||||
|
||||
Foo *time.Time `locationName:"foo" type:"timestamp"`
|
||||
}
|
||||
|
||||
// SetBar sets the Bar field's value.
|
||||
func (s *OutputService3TestShapeTimeContainer) SetBar(v time.Time) *OutputService3TestShapeTimeContainer {
|
||||
s.Bar = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetFoo sets the Foo field's value.
|
||||
@@ -602,7 +629,8 @@ func newOutputService4ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice4protocoltest",
|
||||
ServiceName: "OutputService4ProtocolTest",
|
||||
ServiceID: "OutputService4ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -635,7 +663,7 @@ const opOutputService4TestCaseOperation1 = "OperationName"
|
||||
// OutputService4TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService4TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -654,7 +682,7 @@ const opOutputService4TestCaseOperation1 = "OperationName"
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1Request(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (req *request.Request, output *OutputService4TestShapeOutputService4TestCaseOperation2Output) {
|
||||
func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1Request(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (req *request.Request, output *OutputService4TestShapeOutputService4TestCaseOperation1Output) {
|
||||
op := &request.Operation{
|
||||
Name: opOutputService4TestCaseOperation1,
|
||||
HTTPPath: "/",
|
||||
@@ -664,7 +692,7 @@ func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1Request(inp
|
||||
input = &OutputService4TestShapeOutputService4TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
output = &OutputService4TestShapeOutputService4TestCaseOperation2Output{}
|
||||
output = &OutputService4TestShapeOutputService4TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
return
|
||||
}
|
||||
@@ -677,7 +705,7 @@ func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1Request(inp
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation OutputService4TestCaseOperation1 for usage and error information.
|
||||
func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (*OutputService4TestShapeOutputService4TestCaseOperation2Output, error) {
|
||||
func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1(input *OutputService4TestShapeOutputService4TestCaseOperation1Input) (*OutputService4TestShapeOutputService4TestCaseOperation1Output, error) {
|
||||
req, out := c.OutputService4TestCaseOperation1Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
@@ -691,7 +719,7 @@ func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1(input *Out
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1WithContext(ctx aws.Context, input *OutputService4TestShapeOutputService4TestCaseOperation1Input, opts ...request.Option) (*OutputService4TestShapeOutputService4TestCaseOperation2Output, error) {
|
||||
func (c *OutputService4ProtocolTest) OutputService4TestCaseOperation1WithContext(ctx aws.Context, input *OutputService4TestShapeOutputService4TestCaseOperation1Input, opts ...request.Option) (*OutputService4TestShapeOutputService4TestCaseOperation1Output, error) {
|
||||
req, out := c.OutputService4TestCaseOperation1Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
@@ -703,7 +731,7 @@ const opOutputService4TestCaseOperation2 = "OperationName"
|
||||
// OutputService4TestCaseOperation2Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService4TestCaseOperation2 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -770,6 +798,34 @@ type OutputService4TestShapeOutputService4TestCaseOperation1Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService4TestShapeOutputService4TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
ListMember []*string `type:"list"`
|
||||
|
||||
ListMemberMap []map[string]*string `type:"list"`
|
||||
|
||||
ListMemberStruct []*OutputService4TestShapeStructType `type:"list"`
|
||||
}
|
||||
|
||||
// SetListMember sets the ListMember field's value.
|
||||
func (s *OutputService4TestShapeOutputService4TestCaseOperation1Output) SetListMember(v []*string) *OutputService4TestShapeOutputService4TestCaseOperation1Output {
|
||||
s.ListMember = v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetListMemberMap sets the ListMemberMap field's value.
|
||||
func (s *OutputService4TestShapeOutputService4TestCaseOperation1Output) SetListMemberMap(v []map[string]*string) *OutputService4TestShapeOutputService4TestCaseOperation1Output {
|
||||
s.ListMemberMap = v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetListMemberStruct sets the ListMemberStruct field's value.
|
||||
func (s *OutputService4TestShapeOutputService4TestCaseOperation1Output) SetListMemberStruct(v []*OutputService4TestShapeStructType) *OutputService4TestShapeOutputService4TestCaseOperation1Output {
|
||||
s.ListMemberStruct = v
|
||||
return s
|
||||
}
|
||||
|
||||
type OutputService4TestShapeOutputService4TestCaseOperation2Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
@@ -837,7 +893,8 @@ func newOutputService5ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice5protocoltest",
|
||||
ServiceName: "OutputService5ProtocolTest",
|
||||
ServiceID: "OutputService5ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -870,7 +927,7 @@ const opOutputService5TestCaseOperation1 = "OperationName"
|
||||
// OutputService5TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService5TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -980,7 +1037,8 @@ func newOutputService6ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice6protocoltest",
|
||||
ServiceName: "OutputService6ProtocolTest",
|
||||
ServiceID: "OutputService6ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1013,7 +1071,7 @@ const opOutputService6TestCaseOperation1 = "OperationName"
|
||||
// OutputService6TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService6TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1123,7 +1181,8 @@ func newOutputService7ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice7protocoltest",
|
||||
ServiceName: "OutputService7ProtocolTest",
|
||||
ServiceID: "OutputService7ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1156,7 +1215,7 @@ const opOutputService7TestCaseOperation1 = "OperationName"
|
||||
// OutputService7TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService7TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1251,6 +1310,297 @@ const (
|
||||
JSONEnumTypeBar = "bar"
|
||||
)
|
||||
|
||||
// OutputService8ProtocolTest provides the API operation methods for making requests to
|
||||
// . See this package's package overview docs
|
||||
// for details on the service.
|
||||
//
|
||||
// OutputService8ProtocolTest methods are safe to use concurrently. It is not safe to
|
||||
// modify mutate any of the struct's properties though.
|
||||
type OutputService8ProtocolTest struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// New creates a new instance of the OutputService8ProtocolTest client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
// // Create a OutputService8ProtocolTest client from just a session.
|
||||
// svc := outputservice8protocoltest.New(mySession)
|
||||
//
|
||||
// // Create a OutputService8ProtocolTest client with additional configuration
|
||||
// svc := outputservice8protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func NewOutputService8ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService8ProtocolTest {
|
||||
c := p.ClientConfig("outputservice8protocoltest", cfgs...)
|
||||
return newOutputService8ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newOutputService8ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *OutputService8ProtocolTest {
|
||||
svc := &OutputService8ProtocolTest{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "OutputService8ProtocolTest",
|
||||
ServiceID: "OutputService8ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(jsonrpc.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(jsonrpc.UnmarshalErrorHandler)
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a OutputService8ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *OutputService8ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opOutputService8TestCaseOperation1 = "OperationName"
|
||||
|
||||
// OutputService8TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService8TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See OutputService8TestCaseOperation1 for more information on using the OutputService8TestCaseOperation1
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the OutputService8TestCaseOperation1Request method.
|
||||
// req, resp := client.OutputService8TestCaseOperation1Request(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1Request(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (req *request.Request, output *OutputService8TestShapeOutputService8TestCaseOperation1Output) {
|
||||
op := &request.Operation{
|
||||
Name: opOutputService8TestCaseOperation1,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService8TestShapeOutputService8TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
output = &OutputService8TestShapeOutputService8TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
// OutputService8TestCaseOperation1 API operation for .
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation OutputService8TestCaseOperation1 for usage and error information.
|
||||
func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1(input *OutputService8TestShapeOutputService8TestCaseOperation1Input) (*OutputService8TestShapeOutputService8TestCaseOperation1Output, error) {
|
||||
req, out := c.OutputService8TestCaseOperation1Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// OutputService8TestCaseOperation1WithContext is the same as OutputService8TestCaseOperation1 with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See OutputService8TestCaseOperation1 for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation1WithContext(ctx aws.Context, input *OutputService8TestShapeOutputService8TestCaseOperation1Input, opts ...request.Option) (*OutputService8TestShapeOutputService8TestCaseOperation1Output, error) {
|
||||
req, out := c.OutputService8TestCaseOperation1Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
const opOutputService8TestCaseOperation2 = "OperationName"
|
||||
|
||||
// OutputService8TestCaseOperation2Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService8TestCaseOperation2 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See OutputService8TestCaseOperation2 for more information on using the OutputService8TestCaseOperation2
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the OutputService8TestCaseOperation2Request method.
|
||||
// req, resp := client.OutputService8TestCaseOperation2Request(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation2Request(input *OutputService8TestShapeOutputService8TestCaseOperation2Input) (req *request.Request, output *OutputService8TestShapeOutputService8TestCaseOperation2Output) {
|
||||
op := &request.Operation{
|
||||
Name: opOutputService8TestCaseOperation2,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService8TestShapeOutputService8TestCaseOperation2Input{}
|
||||
}
|
||||
|
||||
output = &OutputService8TestShapeOutputService8TestCaseOperation2Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
// OutputService8TestCaseOperation2 API operation for .
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation OutputService8TestCaseOperation2 for usage and error information.
|
||||
func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation2(input *OutputService8TestShapeOutputService8TestCaseOperation2Input) (*OutputService8TestShapeOutputService8TestCaseOperation2Output, error) {
|
||||
req, out := c.OutputService8TestCaseOperation2Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// OutputService8TestCaseOperation2WithContext is the same as OutputService8TestCaseOperation2 with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See OutputService8TestCaseOperation2 for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation2WithContext(ctx aws.Context, input *OutputService8TestShapeOutputService8TestCaseOperation2Input, opts ...request.Option) (*OutputService8TestShapeOutputService8TestCaseOperation2Output, error) {
|
||||
req, out := c.OutputService8TestCaseOperation2Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
const opOutputService8TestCaseOperation3 = "OperationName"
|
||||
|
||||
// OutputService8TestCaseOperation3Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService8TestCaseOperation3 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See OutputService8TestCaseOperation3 for more information on using the OutputService8TestCaseOperation3
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the OutputService8TestCaseOperation3Request method.
|
||||
// req, resp := client.OutputService8TestCaseOperation3Request(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation3Request(input *OutputService8TestShapeOutputService8TestCaseOperation3Input) (req *request.Request, output *OutputService8TestShapeOutputService8TestCaseOperation3Output) {
|
||||
op := &request.Operation{
|
||||
Name: opOutputService8TestCaseOperation3,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService8TestShapeOutputService8TestCaseOperation3Input{}
|
||||
}
|
||||
|
||||
output = &OutputService8TestShapeOutputService8TestCaseOperation3Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
|
||||
return
|
||||
}
|
||||
|
||||
// OutputService8TestCaseOperation3 API operation for .
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation OutputService8TestCaseOperation3 for usage and error information.
|
||||
func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation3(input *OutputService8TestShapeOutputService8TestCaseOperation3Input) (*OutputService8TestShapeOutputService8TestCaseOperation3Output, error) {
|
||||
req, out := c.OutputService8TestCaseOperation3Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// OutputService8TestCaseOperation3WithContext is the same as OutputService8TestCaseOperation3 with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See OutputService8TestCaseOperation3 for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *OutputService8ProtocolTest) OutputService8TestCaseOperation3WithContext(ctx aws.Context, input *OutputService8TestShapeOutputService8TestCaseOperation3Input, opts ...request.Option) (*OutputService8TestShapeOutputService8TestCaseOperation3Output, error) {
|
||||
req, out := c.OutputService8TestCaseOperation3Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type OutputService8TestShapeOutputService8TestCaseOperation1Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService8TestShapeOutputService8TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService8TestShapeOutputService8TestCaseOperation2Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService8TestShapeOutputService8TestCaseOperation2Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService8TestShapeOutputService8TestCaseOperation3Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService8TestShapeOutputService8TestCaseOperation3Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
//
|
||||
// Tests begin here
|
||||
//
|
||||
@@ -1265,8 +1615,8 @@ func TestOutputService1ProtocolTestScalarMembersCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
jsonrpc.UnmarshalMeta(req)
|
||||
jsonrpc.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1312,8 +1662,8 @@ func TestOutputService2ProtocolTestBlobMembersCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
jsonrpc.UnmarshalMeta(req)
|
||||
jsonrpc.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1334,15 +1684,15 @@ func TestOutputService2ProtocolTestBlobMembersCase1(t *testing.T) {
|
||||
func TestOutputService3ProtocolTestTimestampMembersCase1(t *testing.T) {
|
||||
svc := NewOutputService3ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
|
||||
buf := bytes.NewReader([]byte("{\"TimeMember\": 1398796238, \"StructMember\": {\"foo\": 1398796238}}"))
|
||||
buf := bytes.NewReader([]byte("{\"TimeArg\": 1398796238, \"TimeCustom\": \"Tue, 29 Apr 2014 18:30:38 GMT\", \"TimeFormat\": \"2014-04-29T18:30:38Z\", \"StructMember\": {\"foo\": 1398796238, \"bar\": \"2014-04-29T18:30:38Z\"}}"))
|
||||
req, out := svc.OutputService3TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
jsonrpc.UnmarshalMeta(req)
|
||||
jsonrpc.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1351,10 +1701,19 @@ func TestOutputService3ProtocolTestTimestampMembersCase1(t *testing.T) {
|
||||
if out == nil {
|
||||
t.Errorf("expect not to be nil")
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.StructMember.Foo.String(); e != a {
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.StructMember.Bar.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.TimeMember.String(); e != a {
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.StructMember.Foo.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.TimeArg.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.TimeCustom.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.TimeFormat.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
|
||||
@@ -1370,8 +1729,8 @@ func TestOutputService4ProtocolTestListsCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
jsonrpc.UnmarshalMeta(req)
|
||||
jsonrpc.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1399,8 +1758,8 @@ func TestOutputService4ProtocolTestListsCase2(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
jsonrpc.UnmarshalMeta(req)
|
||||
jsonrpc.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1440,8 +1799,8 @@ func TestOutputService5ProtocolTestMapsCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
jsonrpc.UnmarshalMeta(req)
|
||||
jsonrpc.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1475,8 +1834,8 @@ func TestOutputService6ProtocolTestIgnoresExtraDataCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
jsonrpc.UnmarshalMeta(req)
|
||||
jsonrpc.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1498,8 +1857,8 @@ func TestOutputService7ProtocolTestEnumOutputCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
jsonrpc.UnmarshalMeta(req)
|
||||
jsonrpc.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -1519,3 +1878,72 @@ func TestOutputService7ProtocolTestEnumOutputCase1(t *testing.T) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService8ProtocolTestunmodeledNonjsonResponsePayloadCase1(t *testing.T) {
|
||||
svc := NewOutputService8ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
|
||||
buf := bytes.NewReader([]byte("success"))
|
||||
req, out := svc.OutputService8TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
|
||||
// assert response
|
||||
if out == nil {
|
||||
t.Errorf("expect not to be nil")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService8ProtocolTestunmodeledNonjsonResponsePayloadCase2(t *testing.T) {
|
||||
svc := NewOutputService8ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
|
||||
buf := bytes.NewReader([]byte("\"success\""))
|
||||
req, out := svc.OutputService8TestCaseOperation2Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
|
||||
// assert response
|
||||
if out == nil {
|
||||
t.Errorf("expect not to be nil")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService8ProtocolTestunmodeledNonjsonResponsePayloadCase3(t *testing.T) {
|
||||
svc := NewOutputService8ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
|
||||
buf := bytes.NewReader([]byte("{}"))
|
||||
req, out := svc.OutputService8TestCaseOperation3Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
|
||||
// assert response
|
||||
if out == nil {
|
||||
t.Errorf("expect not to be nil")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// PayloadUnmarshaler provides the interface for unmarshaling a payload's
|
||||
// reader into a SDK shape.
|
||||
type PayloadUnmarshaler interface {
|
||||
UnmarshalPayload(io.Reader, interface{}) error
|
||||
}
|
||||
|
||||
// HandlerPayloadUnmarshal implements the PayloadUnmarshaler from a
|
||||
// HandlerList. This provides the support for unmarshaling a payload reader to
|
||||
// a shape without needing a SDK request first.
|
||||
type HandlerPayloadUnmarshal struct {
|
||||
Unmarshalers request.HandlerList
|
||||
}
|
||||
|
||||
// UnmarshalPayload unmarshals the io.Reader payload into the SDK shape using
|
||||
// the Unmarshalers HandlerList provided. Returns an error if unable
|
||||
// unmarshaling fails.
|
||||
func (h HandlerPayloadUnmarshal) UnmarshalPayload(r io.Reader, v interface{}) error {
|
||||
req := &request.Request{
|
||||
HTTPRequest: &http.Request{},
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 200,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(r),
|
||||
},
|
||||
Data: v,
|
||||
}
|
||||
|
||||
h.Unmarshalers.Run(req)
|
||||
|
||||
return req.Error
|
||||
}
|
||||
|
||||
// PayloadMarshaler provides the interface for marshaling a SDK shape into and
|
||||
// io.Writer.
|
||||
type PayloadMarshaler interface {
|
||||
MarshalPayload(io.Writer, interface{}) error
|
||||
}
|
||||
|
||||
// HandlerPayloadMarshal implements the PayloadMarshaler from a HandlerList.
|
||||
// This provides support for marshaling a SDK shape into an io.Writer without
|
||||
// needing a SDK request first.
|
||||
type HandlerPayloadMarshal struct {
|
||||
Marshalers request.HandlerList
|
||||
}
|
||||
|
||||
// MarshalPayload marshals the SDK shape into the io.Writer using the
|
||||
// Marshalers HandlerList provided. Returns an error if unable if marshal
|
||||
// fails.
|
||||
func (h HandlerPayloadMarshal) MarshalPayload(w io.Writer, v interface{}) error {
|
||||
req := request.New(
|
||||
aws.Config{},
|
||||
metadata.ClientInfo{},
|
||||
request.Handlers{},
|
||||
nil,
|
||||
&request.Operation{HTTPMethod: "GET"},
|
||||
v,
|
||||
nil,
|
||||
)
|
||||
|
||||
h.Marshalers.Run(req)
|
||||
|
||||
if req.Error != nil {
|
||||
return req.Error
|
||||
}
|
||||
|
||||
io.Copy(w, req.GetBody())
|
||||
|
||||
return nil
|
||||
}
|
||||
+12
-6
@@ -5,8 +5,6 @@ import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/awstesting"
|
||||
@@ -117,13 +115,21 @@ func checkForLeak(data interface{}, build, fn func(*request.Request), t *testing
|
||||
fn(req)
|
||||
|
||||
if result.errExists {
|
||||
assert.NotNil(t, req.Error)
|
||||
if err := req.Error; err == nil {
|
||||
t.Errorf("expect error")
|
||||
}
|
||||
} else {
|
||||
assert.Nil(t, req.Error)
|
||||
if err := req.Error; err != nil {
|
||||
t.Errorf("expect nil, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
assert.Equal(t, reader.Closed, result.closed)
|
||||
assert.Equal(t, reader.Size, result.size)
|
||||
if e, a := reader.Closed, result.closed; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := reader.Size, result.size; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONRpc(t *testing.T) {
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ func Build(r *request.Request) {
|
||||
"Version": {r.ClientInfo.APIVersion},
|
||||
}
|
||||
if err := queryutil.Parse(body, r.Params, false); err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed encoding Query request", err)
|
||||
r.Error = awserr.New(request.ErrCodeSerialization, "failed encoding Query request", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+715
-186
File diff suppressed because it is too large
Load Diff
+6
-1
@@ -233,7 +233,12 @@ func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, ta
|
||||
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))
|
||||
format := tag.Get("timestampFormat")
|
||||
if len(format) == 0 {
|
||||
format = protocol.ISO8601TimeFormatName
|
||||
}
|
||||
|
||||
v.Set(name, protocol.FormatTime(format, value))
|
||||
default:
|
||||
return fmt.Errorf("unsupported value for param %s: %v (%s)", name, r.Interface(), r.Type().Name())
|
||||
}
|
||||
|
||||
+5
-1
@@ -23,7 +23,11 @@ func Unmarshal(r *request.Request) {
|
||||
decoder := xml.NewDecoder(r.HTTPResponse.Body)
|
||||
err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result")
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed decoding Query response", err)
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization, "failed decoding Query response", err),
|
||||
r.HTTPResponse.StatusCode,
|
||||
r.RequestID,
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
+44
-41
@@ -2,65 +2,68 @@ package query
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil"
|
||||
)
|
||||
|
||||
type xmlErrorResponse struct {
|
||||
XMLName xml.Name `xml:"ErrorResponse"`
|
||||
Code string `xml:"Error>Code"`
|
||||
Message string `xml:"Error>Message"`
|
||||
RequestID string `xml:"RequestId"`
|
||||
}
|
||||
|
||||
type xmlServiceUnavailableResponse struct {
|
||||
XMLName xml.Name `xml:"ServiceUnavailableException"`
|
||||
}
|
||||
|
||||
// UnmarshalErrorHandler is a name request handler to unmarshal request errors
|
||||
var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalError", Fn: UnmarshalError}
|
||||
|
||||
type xmlErrorResponse struct {
|
||||
Code string `xml:"Error>Code"`
|
||||
Message string `xml:"Error>Message"`
|
||||
RequestID string `xml:"RequestId"`
|
||||
}
|
||||
|
||||
type xmlResponseError struct {
|
||||
xmlErrorResponse
|
||||
}
|
||||
|
||||
func (e *xmlResponseError) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
const svcUnavailableTagName = "ServiceUnavailableException"
|
||||
const errorResponseTagName = "ErrorResponse"
|
||||
|
||||
switch start.Name.Local {
|
||||
case svcUnavailableTagName:
|
||||
e.Code = svcUnavailableTagName
|
||||
e.Message = "service is unavailable"
|
||||
return d.Skip()
|
||||
|
||||
case errorResponseTagName:
|
||||
return d.DecodeElement(&e.xmlErrorResponse, &start)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unknown error response tag, %v", start)
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalError unmarshals an error response for an AWS Query service.
|
||||
func UnmarshalError(r *request.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
|
||||
bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||
var respErr xmlResponseError
|
||||
err := xmlutil.UnmarshalXMLError(&respErr, r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed to read from query HTTP response body", err)
|
||||
return
|
||||
}
|
||||
|
||||
// First check for specific error
|
||||
resp := xmlErrorResponse{}
|
||||
decodeErr := xml.Unmarshal(bodyBytes, &resp)
|
||||
if decodeErr == nil {
|
||||
reqID := resp.RequestID
|
||||
if reqID == "" {
|
||||
reqID = r.RequestID
|
||||
}
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(resp.Code, resp.Message, nil),
|
||||
r.HTTPResponse.StatusCode,
|
||||
reqID,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Check for unhandled error
|
||||
servUnavailResp := xmlServiceUnavailableResponse{}
|
||||
unavailErr := xml.Unmarshal(bodyBytes, &servUnavailResp)
|
||||
if unavailErr == nil {
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New("ServiceUnavailableException", "service is unavailable", nil),
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed to unmarshal error message", err),
|
||||
r.HTTPResponse.StatusCode,
|
||||
r.RequestID,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Failed to retrieve any error message from the response body
|
||||
r.Error = awserr.New("SerializationError",
|
||||
"failed to decode query XML error response", decodeErr)
|
||||
reqID := respErr.RequestID
|
||||
if len(reqID) == 0 {
|
||||
reqID = r.RequestID
|
||||
}
|
||||
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(respErr.Code, respErr.Message, nil),
|
||||
r.HTTPResponse.StatusCode,
|
||||
reqID,
|
||||
)
|
||||
}
|
||||
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
// +build go1.8
|
||||
|
||||
package query
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
func TestUnmarshalError(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Request *request.Request
|
||||
Code, Msg string
|
||||
ReqID string
|
||||
Status int
|
||||
}{
|
||||
"ErrorResponse": {
|
||||
Request: &request.Request{
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 400,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(strings.NewReader(
|
||||
`<ErrorResponse>
|
||||
<Error>
|
||||
<Code>codeAbc</Code><Message>msg123</Message>
|
||||
</Error>
|
||||
<RequestId>reqID123</RequestId>
|
||||
</ErrorResponse>`)),
|
||||
},
|
||||
},
|
||||
Code: "codeAbc", Msg: "msg123",
|
||||
Status: 400, ReqID: "reqID123",
|
||||
},
|
||||
"ServiceUnavailableException": {
|
||||
Request: &request.Request{
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 502,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(strings.NewReader(
|
||||
`<ServiceUnavailableException>
|
||||
<Something>else</Something>
|
||||
</ServiceUnavailableException>`)),
|
||||
},
|
||||
},
|
||||
Code: "ServiceUnavailableException",
|
||||
Msg: "service is unavailable",
|
||||
Status: 502,
|
||||
},
|
||||
"unknown tag": {
|
||||
Request: &request.Request{
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 400,
|
||||
Header: http.Header{},
|
||||
Body: ioutil.NopCloser(strings.NewReader(
|
||||
`<Hello>
|
||||
<World>.</World>
|
||||
</Hello>`)),
|
||||
},
|
||||
},
|
||||
Code: request.ErrCodeSerialization,
|
||||
Msg: "failed to unmarshal error message",
|
||||
Status: 400,
|
||||
},
|
||||
}
|
||||
|
||||
for name, c := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
r := c.Request
|
||||
UnmarshalError(r)
|
||||
if r.Error == nil {
|
||||
t.Fatalf("expect error, got none")
|
||||
}
|
||||
|
||||
aerr := r.Error.(awserr.RequestFailure)
|
||||
if e, a := c.Code, aerr.Code(); e != a {
|
||||
t.Errorf("expect %v code, got %v", e, a)
|
||||
}
|
||||
if e, a := c.Msg, aerr.Message(); e != a {
|
||||
t.Errorf("expect %q message, got %q", e, a)
|
||||
}
|
||||
if e, a := c.ReqID, aerr.RequestID(); e != a {
|
||||
t.Errorf("expect %v request ID, got %v", e, a)
|
||||
}
|
||||
if e, a := c.Status, aerr.StatusCode(); e != a {
|
||||
t.Errorf("expect %v status code, got %v", e, a)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+315
-73
@@ -75,7 +75,8 @@ func newOutputService1ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice1protocoltest",
|
||||
ServiceName: "OutputService1ProtocolTest",
|
||||
ServiceID: "OutputService1ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -108,7 +109,7 @@ const opOutputService1TestCaseOperation1 = "OperationName"
|
||||
// OutputService1TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService1TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -192,7 +193,7 @@ type OutputService1TestShapeOutputService1TestCaseOperation1Output struct {
|
||||
|
||||
Str *string `type:"string"`
|
||||
|
||||
Timestamp *time.Time `type:"timestamp" timestampFormat:"iso8601"`
|
||||
Timestamp *time.Time `type:"timestamp"`
|
||||
|
||||
TrueBool *bool `type:"boolean"`
|
||||
}
|
||||
@@ -282,7 +283,8 @@ func newOutputService2ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice2protocoltest",
|
||||
ServiceName: "OutputService2ProtocolTest",
|
||||
ServiceID: "OutputService2ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -315,7 +317,7 @@ const opOutputService2TestCaseOperation1 = "OperationName"
|
||||
// OutputService2TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService2TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -433,7 +435,8 @@ func newOutputService3ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice3protocoltest",
|
||||
ServiceName: "OutputService3ProtocolTest",
|
||||
ServiceID: "OutputService3ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -466,7 +469,7 @@ const opOutputService3TestCaseOperation1 = "OperationName"
|
||||
// OutputService3TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService3TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -577,7 +580,8 @@ func newOutputService4ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice4protocoltest",
|
||||
ServiceName: "OutputService4ProtocolTest",
|
||||
ServiceID: "OutputService4ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -610,7 +614,7 @@ const opOutputService4TestCaseOperation1 = "OperationName"
|
||||
// OutputService4TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService4TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -720,7 +724,8 @@ func newOutputService5ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice5protocoltest",
|
||||
ServiceName: "OutputService5ProtocolTest",
|
||||
ServiceID: "OutputService5ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -753,7 +758,7 @@ const opOutputService5TestCaseOperation1 = "OperationName"
|
||||
// OutputService5TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService5TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -863,7 +868,8 @@ func newOutputService6ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice6protocoltest",
|
||||
ServiceName: "OutputService6ProtocolTest",
|
||||
ServiceID: "OutputService6ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -896,7 +902,7 @@ const opOutputService6TestCaseOperation1 = "OperationName"
|
||||
// OutputService6TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService6TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1006,7 +1012,8 @@ func newOutputService7ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice7protocoltest",
|
||||
ServiceName: "OutputService7ProtocolTest",
|
||||
ServiceID: "OutputService7ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1039,7 +1046,7 @@ const opOutputService7TestCaseOperation1 = "OperationName"
|
||||
// OutputService7TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService7TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1149,7 +1156,8 @@ func newOutputService8ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice8protocoltest",
|
||||
ServiceName: "OutputService8ProtocolTest",
|
||||
ServiceID: "OutputService8ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1182,7 +1190,7 @@ const opOutputService8TestCaseOperation1 = "OperationName"
|
||||
// OutputService8TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService8TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1320,7 +1328,8 @@ func newOutputService9ProtocolTestClient(cfg aws.Config, handlers request.Handle
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice9protocoltest",
|
||||
ServiceName: "OutputService9ProtocolTest",
|
||||
ServiceID: "OutputService9ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1353,7 +1362,7 @@ const opOutputService9TestCaseOperation1 = "OperationName"
|
||||
// OutputService9TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService9TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1491,7 +1500,8 @@ func newOutputService10ProtocolTestClient(cfg aws.Config, handlers request.Handl
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice10protocoltest",
|
||||
ServiceName: "OutputService10ProtocolTest",
|
||||
ServiceID: "OutputService10ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1524,7 +1534,7 @@ const opOutputService10TestCaseOperation1 = "OperationName"
|
||||
// OutputService10TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService10TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1634,7 +1644,8 @@ func newOutputService11ProtocolTestClient(cfg aws.Config, handlers request.Handl
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice11protocoltest",
|
||||
ServiceName: "OutputService11ProtocolTest",
|
||||
ServiceID: "OutputService11ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1667,7 +1678,7 @@ const opOutputService11TestCaseOperation1 = "OperationName"
|
||||
// OutputService11TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService11TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1789,7 +1800,8 @@ func newOutputService12ProtocolTestClient(cfg aws.Config, handlers request.Handl
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice12protocoltest",
|
||||
ServiceName: "OutputService12ProtocolTest",
|
||||
ServiceID: "OutputService12ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1822,7 +1834,7 @@ const opOutputService12TestCaseOperation1 = "OperationName"
|
||||
// OutputService12TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService12TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -1932,7 +1944,8 @@ func newOutputService13ProtocolTestClient(cfg aws.Config, handlers request.Handl
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice13protocoltest",
|
||||
ServiceName: "OutputService13ProtocolTest",
|
||||
ServiceID: "OutputService13ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -1965,7 +1978,7 @@ const opOutputService13TestCaseOperation1 = "OperationName"
|
||||
// OutputService13TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService13TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -2075,7 +2088,8 @@ func newOutputService14ProtocolTestClient(cfg aws.Config, handlers request.Handl
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice14protocoltest",
|
||||
ServiceName: "OutputService14ProtocolTest",
|
||||
ServiceID: "OutputService14ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -2108,7 +2122,7 @@ const opOutputService14TestCaseOperation1 = "OperationName"
|
||||
// OutputService14TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService14TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -2218,7 +2232,8 @@ func newOutputService15ProtocolTestClient(cfg aws.Config, handlers request.Handl
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice15protocoltest",
|
||||
ServiceName: "OutputService15ProtocolTest",
|
||||
ServiceID: "OutputService15ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -2251,7 +2266,7 @@ const opOutputService15TestCaseOperation1 = "OperationName"
|
||||
// OutputService15TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService15TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -2361,7 +2376,8 @@ func newOutputService16ProtocolTestClient(cfg aws.Config, handlers request.Handl
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "outputservice16protocoltest",
|
||||
ServiceName: "OutputService16ProtocolTest",
|
||||
ServiceID: "OutputService16ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
@@ -2394,7 +2410,7 @@ const opOutputService16TestCaseOperation1 = "OperationName"
|
||||
// OutputService16TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService16TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfuly.
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
@@ -2464,28 +2480,216 @@ type OutputService16TestShapeOutputService16TestCaseOperation1Input struct {
|
||||
type OutputService16TestShapeOutputService16TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
FooEnum *string `type:"string" enum:"OutputService16TestShapeEC2EnumType"`
|
||||
StructMember *OutputService16TestShapeTimeContainer `type:"structure"`
|
||||
|
||||
TimeArg *time.Time `type:"timestamp"`
|
||||
|
||||
TimeCustom *time.Time `type:"timestamp" timestampFormat:"rfc822"`
|
||||
|
||||
TimeFormat *time.Time `type:"timestamp" timestampFormat:"unixTimestamp"`
|
||||
}
|
||||
|
||||
// SetStructMember sets the StructMember field's value.
|
||||
func (s *OutputService16TestShapeOutputService16TestCaseOperation1Output) SetStructMember(v *OutputService16TestShapeTimeContainer) *OutputService16TestShapeOutputService16TestCaseOperation1Output {
|
||||
s.StructMember = v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeArg sets the TimeArg field's value.
|
||||
func (s *OutputService16TestShapeOutputService16TestCaseOperation1Output) SetTimeArg(v time.Time) *OutputService16TestShapeOutputService16TestCaseOperation1Output {
|
||||
s.TimeArg = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeCustom sets the TimeCustom field's value.
|
||||
func (s *OutputService16TestShapeOutputService16TestCaseOperation1Output) SetTimeCustom(v time.Time) *OutputService16TestShapeOutputService16TestCaseOperation1Output {
|
||||
s.TimeCustom = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetTimeFormat sets the TimeFormat field's value.
|
||||
func (s *OutputService16TestShapeOutputService16TestCaseOperation1Output) SetTimeFormat(v time.Time) *OutputService16TestShapeOutputService16TestCaseOperation1Output {
|
||||
s.TimeFormat = &v
|
||||
return s
|
||||
}
|
||||
|
||||
type OutputService16TestShapeTimeContainer struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
Bar *time.Time `locationName:"bar" type:"timestamp" timestampFormat:"unixTimestamp"`
|
||||
|
||||
Foo *time.Time `locationName:"foo" type:"timestamp"`
|
||||
}
|
||||
|
||||
// SetBar sets the Bar field's value.
|
||||
func (s *OutputService16TestShapeTimeContainer) SetBar(v time.Time) *OutputService16TestShapeTimeContainer {
|
||||
s.Bar = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetFoo sets the Foo field's value.
|
||||
func (s *OutputService16TestShapeTimeContainer) SetFoo(v time.Time) *OutputService16TestShapeTimeContainer {
|
||||
s.Foo = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// OutputService17ProtocolTest provides the API operation methods for making requests to
|
||||
// . See this package's package overview docs
|
||||
// for details on the service.
|
||||
//
|
||||
// OutputService17ProtocolTest methods are safe to use concurrently. It is not safe to
|
||||
// modify mutate any of the struct's properties though.
|
||||
type OutputService17ProtocolTest struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// New creates a new instance of the OutputService17ProtocolTest client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
// // Create a OutputService17ProtocolTest client from just a session.
|
||||
// svc := outputservice17protocoltest.New(mySession)
|
||||
//
|
||||
// // Create a OutputService17ProtocolTest client with additional configuration
|
||||
// svc := outputservice17protocoltest.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func NewOutputService17ProtocolTest(p client.ConfigProvider, cfgs ...*aws.Config) *OutputService17ProtocolTest {
|
||||
c := p.ClientConfig("outputservice17protocoltest", cfgs...)
|
||||
return newOutputService17ProtocolTestClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newOutputService17ProtocolTestClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *OutputService17ProtocolTest {
|
||||
svc := &OutputService17ProtocolTest{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: "OutputService17ProtocolTest",
|
||||
ServiceID: "OutputService17ProtocolTest",
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(query.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(query.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(query.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(query.UnmarshalErrorHandler)
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a OutputService17ProtocolTest operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *OutputService17ProtocolTest) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
const opOutputService17TestCaseOperation1 = "OperationName"
|
||||
|
||||
// OutputService17TestCaseOperation1Request generates a "aws/request.Request" representing the
|
||||
// client's request for the OutputService17TestCaseOperation1 operation. The "output" return
|
||||
// value will be populated with the request's response once the request completes
|
||||
// successfully.
|
||||
//
|
||||
// Use "Send" method on the returned Request to send the API call to the service.
|
||||
// the "output" return value is not valid until after Send returns without error.
|
||||
//
|
||||
// See OutputService17TestCaseOperation1 for more information on using the OutputService17TestCaseOperation1
|
||||
// API call, and error handling.
|
||||
//
|
||||
// This method is useful when you want to inject custom logic or configuration
|
||||
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||
//
|
||||
//
|
||||
// // Example sending a request using the OutputService17TestCaseOperation1Request method.
|
||||
// req, resp := client.OutputService17TestCaseOperation1Request(params)
|
||||
//
|
||||
// err := req.Send()
|
||||
// if err == nil { // resp is now filled
|
||||
// fmt.Println(resp)
|
||||
// }
|
||||
func (c *OutputService17ProtocolTest) OutputService17TestCaseOperation1Request(input *OutputService17TestShapeOutputService17TestCaseOperation1Input) (req *request.Request, output *OutputService17TestShapeOutputService17TestCaseOperation1Output) {
|
||||
op := &request.Operation{
|
||||
Name: opOutputService17TestCaseOperation1,
|
||||
HTTPPath: "/",
|
||||
}
|
||||
|
||||
if input == nil {
|
||||
input = &OutputService17TestShapeOutputService17TestCaseOperation1Input{}
|
||||
}
|
||||
|
||||
output = &OutputService17TestShapeOutputService17TestCaseOperation1Output{}
|
||||
req = c.newRequest(op, input, output)
|
||||
return
|
||||
}
|
||||
|
||||
// OutputService17TestCaseOperation1 API operation for .
|
||||
//
|
||||
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||
// with awserr.Error's Code and Message methods to get detailed information about
|
||||
// the error.
|
||||
//
|
||||
// See the AWS API reference guide for 's
|
||||
// API operation OutputService17TestCaseOperation1 for usage and error information.
|
||||
func (c *OutputService17ProtocolTest) OutputService17TestCaseOperation1(input *OutputService17TestShapeOutputService17TestCaseOperation1Input) (*OutputService17TestShapeOutputService17TestCaseOperation1Output, error) {
|
||||
req, out := c.OutputService17TestCaseOperation1Request(input)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
// OutputService17TestCaseOperation1WithContext is the same as OutputService17TestCaseOperation1 with the addition of
|
||||
// the ability to pass a context and additional request options.
|
||||
//
|
||||
// See OutputService17TestCaseOperation1 for details on how to use this API operation.
|
||||
//
|
||||
// The context must be non-nil and will be used for request cancellation. If
|
||||
// the context is nil a panic will occur. In the future the SDK may create
|
||||
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||
// for more information on using Contexts.
|
||||
func (c *OutputService17ProtocolTest) OutputService17TestCaseOperation1WithContext(ctx aws.Context, input *OutputService17TestShapeOutputService17TestCaseOperation1Input, opts ...request.Option) (*OutputService17TestShapeOutputService17TestCaseOperation1Output, error) {
|
||||
req, out := c.OutputService17TestCaseOperation1Request(input)
|
||||
req.SetContext(ctx)
|
||||
req.ApplyOptions(opts...)
|
||||
return out, req.Send()
|
||||
}
|
||||
|
||||
type OutputService17TestShapeOutputService17TestCaseOperation1Input struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
type OutputService17TestShapeOutputService17TestCaseOperation1Output struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
FooEnum *string `type:"string" enum:"OutputService17TestShapeEC2EnumType"`
|
||||
|
||||
ListEnums []*string `type:"list"`
|
||||
}
|
||||
|
||||
// SetFooEnum sets the FooEnum field's value.
|
||||
func (s *OutputService16TestShapeOutputService16TestCaseOperation1Output) SetFooEnum(v string) *OutputService16TestShapeOutputService16TestCaseOperation1Output {
|
||||
func (s *OutputService17TestShapeOutputService17TestCaseOperation1Output) SetFooEnum(v string) *OutputService17TestShapeOutputService17TestCaseOperation1Output {
|
||||
s.FooEnum = &v
|
||||
return s
|
||||
}
|
||||
|
||||
// SetListEnums sets the ListEnums field's value.
|
||||
func (s *OutputService16TestShapeOutputService16TestCaseOperation1Output) SetListEnums(v []*string) *OutputService16TestShapeOutputService16TestCaseOperation1Output {
|
||||
func (s *OutputService17TestShapeOutputService17TestCaseOperation1Output) SetListEnums(v []*string) *OutputService17TestShapeOutputService17TestCaseOperation1Output {
|
||||
s.ListEnums = v
|
||||
return s
|
||||
}
|
||||
|
||||
const (
|
||||
// EC2EnumTypeFoo is a OutputService16TestShapeEC2EnumType enum value
|
||||
// EC2EnumTypeFoo is a OutputService17TestShapeEC2EnumType enum value
|
||||
EC2EnumTypeFoo = "foo"
|
||||
|
||||
// EC2EnumTypeBar is a OutputService16TestShapeEC2EnumType enum value
|
||||
// EC2EnumTypeBar is a OutputService17TestShapeEC2EnumType enum value
|
||||
EC2EnumTypeBar = "bar"
|
||||
)
|
||||
|
||||
@@ -2503,8 +2707,8 @@ func TestOutputService1ProtocolTestScalarMembersCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2534,7 +2738,7 @@ func TestOutputService1ProtocolTestScalarMembersCase1(t *testing.T) {
|
||||
if e, a := "myname", *out.Str; e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.4221728e+09, 0).UTC().String(), out.Timestamp.String(); e != a {
|
||||
if e, a := time.Unix(1.4221728e+09, 0).UTC().String(), out.Timestamp.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := true, *out.TrueBool; e != a {
|
||||
@@ -2553,8 +2757,8 @@ func TestOutputService2ProtocolTestNotAllMembersInResponseCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2579,8 +2783,8 @@ func TestOutputService3ProtocolTestBlobCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2605,8 +2809,8 @@ func TestOutputService4ProtocolTestListsCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2634,8 +2838,8 @@ func TestOutputService5ProtocolTestListWithCustomMemberNameCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2663,8 +2867,8 @@ func TestOutputService6ProtocolTestFlattenedListCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2692,8 +2896,8 @@ func TestOutputService7ProtocolTestFlattenedSingleElementListCase1(t *testing.T)
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2718,8 +2922,8 @@ func TestOutputService8ProtocolTestListOfStructuresCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2759,8 +2963,8 @@ func TestOutputService9ProtocolTestFlattenedListOfStructuresCase1(t *testing.T)
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2800,8 +3004,8 @@ func TestOutputService10ProtocolTestFlattenedListWithLocationNameCase1(t *testin
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2829,8 +3033,8 @@ func TestOutputService11ProtocolTestNormalMapCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2858,8 +3062,8 @@ func TestOutputService12ProtocolTestFlattenedMapCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2887,8 +3091,8 @@ func TestOutputService13ProtocolTestFlattenedMapInShapeDefinitionCase1(t *testin
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2913,8 +3117,8 @@ func TestOutputService14ProtocolTestNamedMapCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2942,8 +3146,8 @@ func TestOutputService15ProtocolTestEmptyStringCase1(t *testing.T) {
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
@@ -2958,18 +3162,56 @@ func TestOutputService15ProtocolTestEmptyStringCase1(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService16ProtocolTestEnumOutputCase1(t *testing.T) {
|
||||
func TestOutputService16ProtocolTestTimestampMembersCase1(t *testing.T) {
|
||||
svc := NewOutputService16ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><FooEnum>foo</FooEnum><ListEnums><member>foo</member><member>bar</member></ListEnums></OperationNameResponse>"))
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><StructMember><foo>2014-04-29T18:30:38Z</foo><bar>1398796238</bar></StructMember><TimeArg>2014-04-29T18:30:38Z</TimeArg><TimeCustom>Tue, 29 Apr 2014 18:30:38 GMT</TimeCustom><TimeFormat>1398796238</TimeFormat><RequestId>requestid</RequestId></OperationNameResponse>"))
|
||||
req, out := svc.OutputService16TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
query.UnmarshalMeta(req)
|
||||
query.Unmarshal(req)
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
|
||||
// assert response
|
||||
if out == nil {
|
||||
t.Errorf("expect not to be nil")
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.StructMember.Bar.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.StructMember.Foo.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.TimeArg.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.TimeCustom.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if e, a := time.Unix(1.398796238e+09, 0).UTC().String(), out.TimeFormat.UTC().String(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestOutputService17ProtocolTestEnumOutputCase1(t *testing.T) {
|
||||
svc := NewOutputService17ProtocolTest(unit.Session, &aws.Config{Endpoint: aws.String("https://test")})
|
||||
|
||||
buf := bytes.NewReader([]byte("<OperationNameResponse><FooEnum>foo</FooEnum><ListEnums><member>foo</member><member>bar</member></ListEnums></OperationNameResponse>"))
|
||||
req, out := svc.OutputService17TestCaseOperation1Request(nil)
|
||||
req.HTTPResponse = &http.Response{StatusCode: 200, Body: ioutil.NopCloser(buf), Header: http.Header{}}
|
||||
|
||||
// set headers
|
||||
|
||||
// unmarshal response
|
||||
req.Handlers.UnmarshalMeta.Run(req)
|
||||
req.Handlers.Unmarshal.Run(req)
|
||||
if req.Error != nil {
|
||||
t.Errorf("expect not error, got %v", req.Error)
|
||||
}
|
||||
|
||||
+29
-10
@@ -20,14 +20,13 @@ import (
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
)
|
||||
|
||||
// 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
|
||||
|
||||
var errValueNotSet = fmt.Errorf("value not set")
|
||||
|
||||
var byteSliceType = reflect.TypeOf([]byte{})
|
||||
|
||||
func init() {
|
||||
for i := 0; i < len(noEscape); i++ {
|
||||
// AWS expects every character except these to be escaped
|
||||
@@ -97,6 +96,14 @@ func buildLocationElements(r *request.Request, v reflect.Value, buildGETQuery bo
|
||||
continue
|
||||
}
|
||||
|
||||
// Support the ability to customize values to be marshaled as a
|
||||
// blob even though they were modeled as a string. Required for S3
|
||||
// API operations like SSECustomerKey is modeled as stirng but
|
||||
// required to be base64 encoded in request.
|
||||
if field.Tag.Get("marshal-as") == "blob" {
|
||||
m = m.Convert(byteSliceType)
|
||||
}
|
||||
|
||||
var err error
|
||||
switch field.Tag.Get("location") {
|
||||
case "headers": // header maps
|
||||
@@ -140,7 +147,7 @@ func buildBody(r *request.Request, v reflect.Value) {
|
||||
case string:
|
||||
r.SetStringBody(reader)
|
||||
default:
|
||||
r.Error = awserr.New("SerializationError",
|
||||
r.Error = awserr.New(request.ErrCodeSerialization,
|
||||
"failed to encode REST request",
|
||||
fmt.Errorf("unknown payload type %s", payload.Type()))
|
||||
}
|
||||
@@ -155,9 +162,12 @@ func buildHeader(header *http.Header, v reflect.Value, name string, tag reflect.
|
||||
if err == errValueNotSet {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return awserr.New("SerializationError", "failed to encode REST request", err)
|
||||
return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err)
|
||||
}
|
||||
|
||||
name = strings.TrimSpace(name)
|
||||
str = strings.TrimSpace(str)
|
||||
|
||||
header.Add(name, str)
|
||||
|
||||
return nil
|
||||
@@ -170,11 +180,13 @@ func buildHeaderMap(header *http.Header, v reflect.Value, tag reflect.StructTag)
|
||||
if err == errValueNotSet {
|
||||
continue
|
||||
} else if err != nil {
|
||||
return awserr.New("SerializationError", "failed to encode REST request", err)
|
||||
return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err)
|
||||
|
||||
}
|
||||
keyStr := strings.TrimSpace(key.String())
|
||||
str = strings.TrimSpace(str)
|
||||
|
||||
header.Add(prefix+key.String(), str)
|
||||
header.Add(prefix+keyStr, str)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -184,7 +196,7 @@ func buildURI(u *url.URL, v reflect.Value, name string, tag reflect.StructTag) e
|
||||
if err == errValueNotSet {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return awserr.New("SerializationError", "failed to encode REST request", err)
|
||||
return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err)
|
||||
}
|
||||
|
||||
u.Path = strings.Replace(u.Path, "{"+name+"}", value, -1)
|
||||
@@ -217,7 +229,7 @@ func buildQueryString(query url.Values, v reflect.Value, name string, tag reflec
|
||||
if err == errValueNotSet {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return awserr.New("SerializationError", "failed to encode REST request", err)
|
||||
return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err)
|
||||
}
|
||||
query.Set(name, str)
|
||||
}
|
||||
@@ -270,7 +282,14 @@ func convertType(v reflect.Value, tag reflect.StructTag) (str string, err error)
|
||||
case float64:
|
||||
str = strconv.FormatFloat(value, 'f', -1, 64)
|
||||
case time.Time:
|
||||
str = value.UTC().Format(RFC822)
|
||||
format := tag.Get("timestampFormat")
|
||||
if len(format) == 0 {
|
||||
format = protocol.RFC822TimeFormatName
|
||||
if tag.Get("location") == "querystring" {
|
||||
format = protocol.ISO8601TimeFormatName
|
||||
}
|
||||
}
|
||||
str = protocol.FormatTime(format, value)
|
||||
case aws.JSONValue:
|
||||
if len(value) == 0 {
|
||||
return "", errValueNotSet
|
||||
|
||||
+11
-7
@@ -57,7 +57,7 @@ func unmarshalBody(r *request.Request, v reflect.Value) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
b, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
|
||||
r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err)
|
||||
} else {
|
||||
payload.Set(reflect.ValueOf(b))
|
||||
}
|
||||
@@ -65,7 +65,7 @@ func unmarshalBody(r *request.Request, v reflect.Value) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
b, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
|
||||
r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err)
|
||||
} else {
|
||||
str := string(b)
|
||||
payload.Set(reflect.ValueOf(&str))
|
||||
@@ -77,7 +77,7 @@ func unmarshalBody(r *request.Request, v reflect.Value) {
|
||||
case "io.ReadSeeker":
|
||||
b, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError",
|
||||
r.Error = awserr.New(request.ErrCodeSerialization,
|
||||
"failed to read response body", err)
|
||||
return
|
||||
}
|
||||
@@ -85,7 +85,7 @@ func unmarshalBody(r *request.Request, v reflect.Value) {
|
||||
default:
|
||||
io.Copy(ioutil.Discard, r.HTTPResponse.Body)
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
r.Error = awserr.New("SerializationError",
|
||||
r.Error = awserr.New(request.ErrCodeSerialization,
|
||||
"failed to decode REST response",
|
||||
fmt.Errorf("unknown payload type %s", payload.Type()))
|
||||
}
|
||||
@@ -115,14 +115,14 @@ func unmarshalLocationElements(r *request.Request, v reflect.Value) {
|
||||
case "header":
|
||||
err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name), field.Tag)
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
|
||||
r.Error = awserr.New(request.ErrCodeSerialization, "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 = awserr.New("SerializationError", "failed to decode REST response", err)
|
||||
r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -198,7 +198,11 @@ func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) erro
|
||||
}
|
||||
v.Set(reflect.ValueOf(&f))
|
||||
case *time.Time:
|
||||
t, err := time.Parse(RFC822, header)
|
||||
format := tag.Get("timestampFormat")
|
||||
if len(format) == 0 {
|
||||
format = protocol.RFC822TimeFormatName
|
||||
}
|
||||
t, err := protocol.ParseTime(format, header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+1242
-364
File diff suppressed because it is too large
Load Diff
+11
-15
@@ -6,12 +6,11 @@ package restjson
|
||||
//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/rest-json.json unmarshal_test.go
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/rest"
|
||||
)
|
||||
@@ -33,6 +32,9 @@ func Build(r *request.Request) {
|
||||
rest.Build(r)
|
||||
|
||||
if t := rest.PayloadType(r.Params); t == "structure" || t == "" {
|
||||
if v := r.HTTPRequest.Header.Get("Content-Type"); len(v) == 0 {
|
||||
r.HTTPRequest.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
jsonrpc.Build(r)
|
||||
}
|
||||
}
|
||||
@@ -54,26 +56,20 @@ func UnmarshalMeta(r *request.Request) {
|
||||
// UnmarshalError unmarshals a response error for the REST JSON protocol.
|
||||
func UnmarshalError(r *request.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
code := r.HTTPResponse.Header.Get("X-Amzn-Errortype")
|
||||
bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||
|
||||
var jsonErr jsonErrorResponse
|
||||
err := jsonutil.UnmarshalJSONError(&jsonErr, r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed reading REST JSON error response", err)
|
||||
return
|
||||
}
|
||||
if len(bodyBytes) == 0 {
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New("SerializationError", r.HTTPResponse.Status, nil),
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed to unmarshal response error", err),
|
||||
r.HTTPResponse.StatusCode,
|
||||
"",
|
||||
r.RequestID,
|
||||
)
|
||||
return
|
||||
}
|
||||
var jsonErr jsonErrorResponse
|
||||
if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed decoding REST JSON error response", err)
|
||||
return
|
||||
}
|
||||
|
||||
code := r.HTTPResponse.Header.Get("X-Amzn-Errortype")
|
||||
if code == "" {
|
||||
code = jsonErr.Code
|
||||
}
|
||||
|
||||
Generated
Vendored
+79
@@ -0,0 +1,79 @@
|
||||
// +build go1.8
|
||||
|
||||
package restjson
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
func TestUnmarshalError_SerializationError(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Request *request.Request
|
||||
ExpectMsg string
|
||||
ExpectBytes []byte
|
||||
}{
|
||||
"empty body": {
|
||||
Request: &request.Request{
|
||||
Data: &struct{}{},
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 400,
|
||||
Header: http.Header{
|
||||
"X-Amzn-Requestid": []string{"abc123"},
|
||||
},
|
||||
Body: ioutil.NopCloser(
|
||||
bytes.NewReader([]byte{}),
|
||||
),
|
||||
},
|
||||
},
|
||||
ExpectMsg: "error message missing",
|
||||
},
|
||||
"HTML body": {
|
||||
Request: &request.Request{
|
||||
Data: &struct{}{},
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 400,
|
||||
Header: http.Header{
|
||||
"X-Amzn-Requestid": []string{"abc123"},
|
||||
},
|
||||
Body: ioutil.NopCloser(
|
||||
bytes.NewReader([]byte(`<html></html>`)),
|
||||
),
|
||||
},
|
||||
},
|
||||
ExpectBytes: []byte(`<html></html>`),
|
||||
ExpectMsg: "failed decoding",
|
||||
},
|
||||
}
|
||||
|
||||
for name, c := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
req := c.Request
|
||||
|
||||
UnmarshalError(req)
|
||||
if req.Error == nil {
|
||||
t.Fatal("expect error, got none")
|
||||
}
|
||||
|
||||
aerr := req.Error.(awserr.RequestFailure)
|
||||
if e, a := request.ErrCodeSerialization, aerr.Code(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
|
||||
uerr := aerr.OrigErr().(awserr.UnmarshalError)
|
||||
if e, a := c.ExpectMsg, uerr.Message(); !strings.Contains(a, e) {
|
||||
t.Errorf("Expect %q, in %q", e, a)
|
||||
}
|
||||
if e, a := c.ExpectBytes, uerr.Bytes(); !bytes.Equal(e, a) {
|
||||
t.Errorf("expect:\n%v\nactual:\n%v", hex.Dump(e), hex.Dump(a))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+549
-347
File diff suppressed because it is too large
Load Diff
+2172
-1275
File diff suppressed because it is too large
Load Diff
+12
-2
@@ -36,7 +36,12 @@ func Build(r *request.Request) {
|
||||
var buf bytes.Buffer
|
||||
err := xmlutil.BuildXML(r.Params, xml.NewEncoder(&buf))
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed to encode rest XML request", err)
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed to encode rest XML request", err),
|
||||
r.HTTPResponse.StatusCode,
|
||||
r.RequestID,
|
||||
)
|
||||
return
|
||||
}
|
||||
r.SetBufferBody(buf.Bytes())
|
||||
@@ -50,7 +55,12 @@ func Unmarshal(r *request.Request) {
|
||||
decoder := xml.NewDecoder(r.HTTPResponse.Body)
|
||||
err := xmlutil.UnmarshalXML(r.Data, decoder, "")
|
||||
if err != nil {
|
||||
r.Error = awserr.New("SerializationError", "failed to decode REST XML response", err)
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed to decode REST XML response", err),
|
||||
r.HTTPResponse.StatusCode,
|
||||
r.RequestID,
|
||||
)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
|
||||
+608
-213
File diff suppressed because it is too large
Load Diff
+72
@@ -0,0 +1,72 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Names of time formats supported by the SDK
|
||||
const (
|
||||
RFC822TimeFormatName = "rfc822"
|
||||
ISO8601TimeFormatName = "iso8601"
|
||||
UnixTimeFormatName = "unixTimestamp"
|
||||
)
|
||||
|
||||
// Time formats supported by the SDK
|
||||
const (
|
||||
// RFC 7231#section-7.1.1.1 timetamp format. e.g Tue, 29 Apr 2014 18:30:38 GMT
|
||||
RFC822TimeFormat = "Mon, 2 Jan 2006 15:04:05 GMT"
|
||||
|
||||
// RFC3339 a subset of the ISO8601 timestamp format. e.g 2014-04-29T18:30:38Z
|
||||
ISO8601TimeFormat = "2006-01-02T15:04:05Z"
|
||||
)
|
||||
|
||||
// IsKnownTimestampFormat returns if the timestamp format name
|
||||
// is know to the SDK's protocols.
|
||||
func IsKnownTimestampFormat(name string) bool {
|
||||
switch name {
|
||||
case RFC822TimeFormatName:
|
||||
fallthrough
|
||||
case ISO8601TimeFormatName:
|
||||
fallthrough
|
||||
case UnixTimeFormatName:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// FormatTime returns a string value of the time.
|
||||
func FormatTime(name string, t time.Time) string {
|
||||
t = t.UTC()
|
||||
|
||||
switch name {
|
||||
case RFC822TimeFormatName:
|
||||
return t.Format(RFC822TimeFormat)
|
||||
case ISO8601TimeFormatName:
|
||||
return t.Format(ISO8601TimeFormat)
|
||||
case UnixTimeFormatName:
|
||||
return strconv.FormatInt(t.Unix(), 10)
|
||||
default:
|
||||
panic("unknown timestamp format name, " + name)
|
||||
}
|
||||
}
|
||||
|
||||
// ParseTime attempts to parse the time given the format. Returns
|
||||
// the time if it was able to be parsed, and fails otherwise.
|
||||
func ParseTime(formatName, value string) (time.Time, error) {
|
||||
switch formatName {
|
||||
case RFC822TimeFormatName:
|
||||
return time.Parse(RFC822TimeFormat, value)
|
||||
case ISO8601TimeFormatName:
|
||||
return time.Parse(ISO8601TimeFormat, value)
|
||||
case UnixTimeFormatName:
|
||||
v, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
return time.Unix(int64(v), 0), nil
|
||||
default:
|
||||
panic("unknown timestamp format name, " + formatName)
|
||||
}
|
||||
}
|
||||
+130
-5
@@ -1,13 +1,19 @@
|
||||
package protocol_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/ec2query"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/query"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/restjson"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/restxml"
|
||||
)
|
||||
|
||||
type mockCloser struct {
|
||||
@@ -27,14 +33,133 @@ func TestUnmarshalDrainBody(t *testing.T) {
|
||||
}}
|
||||
|
||||
protocol.UnmarshalDiscardBody(r)
|
||||
assert.NoError(t, r.Error)
|
||||
assert.Equal(t, 0, b.Len())
|
||||
assert.True(t, b.Closed)
|
||||
if err := r.Error; err != nil {
|
||||
t.Errorf("expect nil, %v", err)
|
||||
}
|
||||
if e, a := 0, b.Len(); e != a {
|
||||
t.Errorf("expect %v, got %v", e, a)
|
||||
}
|
||||
if !b.Closed {
|
||||
t.Errorf("expect true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalDrainBodyNoBody(t *testing.T) {
|
||||
r := &request.Request{HTTPResponse: &http.Response{}}
|
||||
|
||||
protocol.UnmarshalDiscardBody(r)
|
||||
assert.NoError(t, r.Error)
|
||||
if err := r.Error; err != nil {
|
||||
t.Errorf("expect nil, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalSeriaizationError(t *testing.T) {
|
||||
|
||||
type testOutput struct {
|
||||
_ struct{}
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
r request.Request
|
||||
unmarshalFn func(*request.Request)
|
||||
expectedError awserr.RequestFailure
|
||||
}{
|
||||
{
|
||||
name: "jsonrpc",
|
||||
r: request.Request{
|
||||
Data: &testOutput{},
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 502,
|
||||
Body: ioutil.NopCloser(strings.NewReader("invalid json")),
|
||||
},
|
||||
},
|
||||
unmarshalFn: jsonrpc.Unmarshal,
|
||||
expectedError: awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization, "", nil),
|
||||
502,
|
||||
"",
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "ec2query",
|
||||
r: request.Request{
|
||||
Data: &testOutput{},
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 111,
|
||||
Body: ioutil.NopCloser(strings.NewReader("<<>>>>>>")),
|
||||
},
|
||||
},
|
||||
unmarshalFn: ec2query.Unmarshal,
|
||||
expectedError: awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization, "", nil),
|
||||
111,
|
||||
"",
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "query",
|
||||
r: request.Request{
|
||||
Operation: &request.Operation{
|
||||
Name: "Foo",
|
||||
},
|
||||
Data: &testOutput{},
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 1,
|
||||
Body: ioutil.NopCloser(strings.NewReader("<<>>>>>>")),
|
||||
},
|
||||
},
|
||||
unmarshalFn: query.Unmarshal,
|
||||
expectedError: awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization, "", nil),
|
||||
1,
|
||||
"",
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "restjson",
|
||||
r: request.Request{
|
||||
Data: &testOutput{},
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 123,
|
||||
Body: ioutil.NopCloser(strings.NewReader("invalid json")),
|
||||
},
|
||||
},
|
||||
unmarshalFn: restjson.Unmarshal,
|
||||
expectedError: awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization, "", nil),
|
||||
123,
|
||||
"",
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "restxml",
|
||||
r: request.Request{
|
||||
Data: &testOutput{},
|
||||
HTTPResponse: &http.Response{
|
||||
StatusCode: 456,
|
||||
Body: ioutil.NopCloser(strings.NewReader("<<>>>>>>")),
|
||||
},
|
||||
},
|
||||
unmarshalFn: restxml.Unmarshal,
|
||||
expectedError: awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization, "", nil),
|
||||
456,
|
||||
"",
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
c.unmarshalFn(&c.r)
|
||||
|
||||
rfErr, ok := c.r.Error.(awserr.RequestFailure)
|
||||
if !ok {
|
||||
t.Errorf("%s: expected awserr.RequestFailure, but received %T", c.name, c.r.Error)
|
||||
}
|
||||
|
||||
if e, a := c.expectedError.StatusCode(), rfErr.StatusCode(); e != a {
|
||||
t.Errorf("%s: expected %v, but received %v", c.name, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+21
-11
@@ -13,9 +13,13 @@ import (
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
)
|
||||
|
||||
// BuildXML will serialize params into an xml.Encoder.
|
||||
// Error will be returned if the serialization of any of the params or nested values fails.
|
||||
// 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 {
|
||||
return buildXML(params, e, false)
|
||||
}
|
||||
|
||||
func buildXML(params interface{}, e *xml.Encoder, sorted bool) error {
|
||||
b := xmlBuilder{encoder: e, namespaces: map[string]string{}}
|
||||
root := NewXMLElement(xml.Name{})
|
||||
if err := b.buildValue(reflect.ValueOf(params), root, ""); err != nil {
|
||||
@@ -23,7 +27,7 @@ func BuildXML(params interface{}, e *xml.Encoder) error {
|
||||
}
|
||||
for _, c := range root.Children {
|
||||
for _, v := range c {
|
||||
return StructToXML(e, v, false)
|
||||
return StructToXML(e, v, sorted)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -83,15 +87,13 @@ func (b *xmlBuilder) buildValue(value reflect.Value, current *XMLNode, tag refle
|
||||
}
|
||||
}
|
||||
|
||||
// buildStruct adds a struct and its fields to the current XMLNode. All fields any any nested
|
||||
// buildStruct adds a struct and its fields to the current XMLNode. All fields and 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)
|
||||
@@ -119,6 +121,8 @@ func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag refl
|
||||
child.Attr = append(child.Attr, ns)
|
||||
}
|
||||
|
||||
var payloadFields, nonPayloadFields int
|
||||
|
||||
t := value.Type()
|
||||
for i := 0; i < value.NumField(); i++ {
|
||||
member := elemOf(value.Field(i))
|
||||
@@ -133,8 +137,10 @@ func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag refl
|
||||
|
||||
mTag := field.Tag
|
||||
if mTag.Get("location") != "" { // skip non-body members
|
||||
nonPayloadFields++
|
||||
continue
|
||||
}
|
||||
payloadFields++
|
||||
|
||||
if protocol.CanSetIdempotencyToken(value.Field(i), field) {
|
||||
token := protocol.GetIdempotencyToken()
|
||||
@@ -149,11 +155,11 @@ func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag refl
|
||||
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
|
||||
// Only case where the child shape is not added is if the shape only contains
|
||||
// non-payload fields, e.g headers/query.
|
||||
if !(payloadFields == 0 && nonPayloadFields > 0) {
|
||||
current.AddChild(child)
|
||||
}
|
||||
|
||||
@@ -278,8 +284,12 @@ func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag refl
|
||||
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)
|
||||
format := tag.Get("timestampFormat")
|
||||
if len(format) == 0 {
|
||||
format = protocol.ISO8601TimeFormatName
|
||||
}
|
||||
|
||||
str = protocol.FormatTime(format, converted)
|
||||
default:
|
||||
return fmt.Errorf("unsupported value for param %s: %v (%s)",
|
||||
tag.Get("locationName"), value.Interface(), value.Type().Name())
|
||||
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
// +build go1.7
|
||||
|
||||
package xmlutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
type implicitPayload struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
StrVal *string `type:"string"`
|
||||
Second *nestedType `type:"structure"`
|
||||
Third *nestedType `type:"structure"`
|
||||
}
|
||||
|
||||
type namedImplicitPayload struct {
|
||||
_ struct{} `type:"structure" locationName:"namedPayload"`
|
||||
|
||||
StrVal *string `type:"string"`
|
||||
Second *nestedType `type:"structure"`
|
||||
Third *nestedType `type:"structure"`
|
||||
}
|
||||
|
||||
type explicitPayload struct {
|
||||
_ struct{} `type:"structure" payload:"Second"`
|
||||
|
||||
Second *nestedType `type:"structure" locationName:"Second"`
|
||||
}
|
||||
|
||||
type useEmptyNested struct {
|
||||
_ struct{} `type:"structure" locationName:"useEmptyNested"`
|
||||
|
||||
StrVal *string `type:"string"`
|
||||
Empty *emptyType `type:"structure"`
|
||||
}
|
||||
|
||||
type useIgnoreNested struct {
|
||||
_ struct{} `type:"structure" locationName:"useIgnoreNested"`
|
||||
StrVal *string `type:"string"`
|
||||
Ignore *ignoreNested `type:"structure"`
|
||||
}
|
||||
|
||||
type skipNonPayload struct {
|
||||
_ struct{} `type:"structure" locationName:"skipNonPayload"`
|
||||
Field *string `type:"string" location:"header"`
|
||||
}
|
||||
type namedEmptyPayload struct {
|
||||
_ struct{} `type:"structure" locationName:"namedEmptyPayload"`
|
||||
}
|
||||
|
||||
type nestedType struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
IntVal *int64 `type:"integer"`
|
||||
StrVal *string `type:"string"`
|
||||
}
|
||||
|
||||
type emptyType struct {
|
||||
_ struct{} `type:"structure"`
|
||||
}
|
||||
|
||||
type ignoreNested struct {
|
||||
_ struct{} `type:"structure"`
|
||||
|
||||
IgnoreMe *string `type:"string" ignore:"true"`
|
||||
}
|
||||
|
||||
func TestBuildXML(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Input interface{}
|
||||
Expect string
|
||||
}{
|
||||
"explicit payload": {
|
||||
Input: &explicitPayload{
|
||||
Second: &nestedType{
|
||||
IntVal: aws.Int64(1234),
|
||||
StrVal: aws.String("string value"),
|
||||
},
|
||||
},
|
||||
Expect: `<Second><IntVal>1234</IntVal><StrVal>string value</StrVal></Second>`,
|
||||
},
|
||||
"implicit payload": {
|
||||
Input: &implicitPayload{
|
||||
StrVal: aws.String("string value"),
|
||||
Second: &nestedType{
|
||||
IntVal: aws.Int64(1111),
|
||||
StrVal: aws.String("second string"),
|
||||
},
|
||||
Third: &nestedType{
|
||||
IntVal: aws.Int64(2222),
|
||||
StrVal: aws.String("third string"),
|
||||
},
|
||||
},
|
||||
Expect: `<Second><IntVal>1111</IntVal><StrVal>second string</StrVal></Second><StrVal>string value</StrVal><Third><IntVal>2222</IntVal><StrVal>third string</StrVal></Third>`,
|
||||
},
|
||||
"named implicit payload": {
|
||||
Input: &namedImplicitPayload{
|
||||
StrVal: aws.String("string value"),
|
||||
Second: &nestedType{
|
||||
IntVal: aws.Int64(1111),
|
||||
StrVal: aws.String("second string"),
|
||||
},
|
||||
Third: &nestedType{
|
||||
IntVal: aws.Int64(2222),
|
||||
StrVal: aws.String("third string"),
|
||||
},
|
||||
},
|
||||
Expect: `<namedPayload><Second><IntVal>1111</IntVal><StrVal>second string</StrVal></Second><StrVal>string value</StrVal><Third><IntVal>2222</IntVal><StrVal>third string</StrVal></Third></namedPayload>`,
|
||||
},
|
||||
"empty with fields nested type": {
|
||||
Input: &namedImplicitPayload{
|
||||
StrVal: aws.String("string value"),
|
||||
Second: &nestedType{},
|
||||
Third: &nestedType{
|
||||
IntVal: aws.Int64(2222),
|
||||
StrVal: aws.String("third string"),
|
||||
},
|
||||
},
|
||||
Expect: `<namedPayload><Second></Second><StrVal>string value</StrVal><Third><IntVal>2222</IntVal><StrVal>third string</StrVal></Third></namedPayload>`,
|
||||
},
|
||||
"empty no fields nested type": {
|
||||
Input: &useEmptyNested{
|
||||
StrVal: aws.String("string value"),
|
||||
Empty: &emptyType{},
|
||||
},
|
||||
Expect: `<useEmptyNested><Empty></Empty><StrVal>string value</StrVal></useEmptyNested>`,
|
||||
},
|
||||
"ignored nested field": {
|
||||
Input: &useIgnoreNested{
|
||||
StrVal: aws.String("string value"),
|
||||
Ignore: &ignoreNested{
|
||||
IgnoreMe: aws.String("abc123"),
|
||||
},
|
||||
},
|
||||
Expect: `<useIgnoreNested><Ignore></Ignore><StrVal>string value</StrVal></useIgnoreNested>`,
|
||||
},
|
||||
"skip non payload root": {
|
||||
Input: &skipNonPayload{
|
||||
Field: aws.String("value"),
|
||||
},
|
||||
Expect: "",
|
||||
},
|
||||
"skip empty root": {
|
||||
Input: &emptyType{},
|
||||
Expect: "",
|
||||
},
|
||||
"named empty payload": {
|
||||
Input: &namedEmptyPayload{},
|
||||
Expect: "<namedEmptyPayload></namedEmptyPayload>",
|
||||
},
|
||||
}
|
||||
|
||||
for name, c := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
var w bytes.Buffer
|
||||
if err := buildXML(c.Input, xml.NewEncoder(&w), true); err != nil {
|
||||
t.Fatalf("expect no error, %v", err)
|
||||
}
|
||||
|
||||
if e, a := c.Expect, w.String(); e != a {
|
||||
t.Errorf("expect:\n%s\nactual:\n%s\n", e, a)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+35
-4
@@ -1,6 +1,7 @@
|
||||
package xmlutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
@@ -9,8 +10,28 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
)
|
||||
|
||||
// UnmarshalXMLError unmarshals the XML error from the stream into the value
|
||||
// type specified. The value must be a pointer. If the message fails to
|
||||
// unmarshal, the message content will be included in the returned error as a
|
||||
// awserr.UnmarshalError.
|
||||
func UnmarshalXMLError(v interface{}, stream io.Reader) error {
|
||||
var errBuf bytes.Buffer
|
||||
body := io.TeeReader(stream, &errBuf)
|
||||
|
||||
err := xml.NewDecoder(body).Decode(v)
|
||||
if err != nil && err != io.EOF {
|
||||
return awserr.NewUnmarshalError(err,
|
||||
"failed to unmarshal error message", errBuf.Bytes())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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.
|
||||
@@ -52,9 +73,15 @@ func parse(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
||||
if t == "" {
|
||||
switch rtype.Kind() {
|
||||
case reflect.Struct:
|
||||
t = "structure"
|
||||
// also it can't be a time object
|
||||
if _, ok := r.Interface().(*time.Time); !ok {
|
||||
t = "structure"
|
||||
}
|
||||
case reflect.Slice:
|
||||
t = "list"
|
||||
// also it can't be a byte slice
|
||||
if _, ok := r.Interface().([]byte); !ok {
|
||||
t = "list"
|
||||
}
|
||||
case reflect.Map:
|
||||
t = "map"
|
||||
}
|
||||
@@ -247,8 +274,12 @@ func parseScalar(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
||||
}
|
||||
r.Set(reflect.ValueOf(&v))
|
||||
case *time.Time:
|
||||
const ISO8601UTC = "2006-01-02T15:04:05Z"
|
||||
t, err := time.Parse(ISO8601UTC, node.Text)
|
||||
format := tag.Get("timestampFormat")
|
||||
if len(format) == 0 {
|
||||
format = protocol.ISO8601TimeFormatName
|
||||
}
|
||||
|
||||
t, err := protocol.ParseTime(format, node.Text)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+1
@@ -29,6 +29,7 @@ func NewXMLElement(name xml.Name) *XMLNode {
|
||||
|
||||
// AddChild adds child to the XMLNode.
|
||||
func (n *XMLNode) AddChild(child *XMLNode) {
|
||||
child.parent = n
|
||||
if _, ok := n.Children[child.Name.Local]; !ok {
|
||||
n.Children[child.Name.Local] = []*XMLNode{}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user