diff --git a/service/apigateway/internal/awsrestjson/marshal.go b/service/apigateway/internal/awsrestjson/marshal.go index f3177ec341f..09090a99c04 100644 --- a/service/apigateway/internal/awsrestjson/marshal.go +++ b/service/apigateway/internal/awsrestjson/marshal.go @@ -10,12 +10,14 @@ import ( "github.com/aws/aws-sdk-go-v2/service/apigateway/types" ) -// ProtoGetApiKeyMarshaler defines marshaler for ProtoGetApiKey operation -type ProtoGetApiKeyMarshaler struct { +// ProtoGetAPIKeyMarshaler defines marshaler for ProtoGetApiKey operation +type ProtoGetAPIKeyMarshaler struct { Input *types.GetApiKeyInput } -func (m ProtoGetApiKeyMarshaler) MarshalOperation(r *aws.Request) { +// Marshal Operation is the top level method used within a handler stack to marshal an operation +// This method calls appropriate marshal shape functions as per the input shape and protocol used by the service. +func (m ProtoGetAPIKeyMarshaler) MarshalOperation(r *aws.Request) { var err error encoder := v2.NewEncoder(r.HTTPRequest) // adds content-type header @@ -32,6 +34,8 @@ func (m ProtoGetApiKeyMarshaler) MarshalOperation(r *aws.Request) { } } +// MarshalGetApiKeyInputShapeAWSREST is a stand alone function used to marshal the HTTP bindings a input shape. +// This method uses the rest encoder utility func MarshalGetApiKeyInputShapeAWSREST(input *types.GetApiKeyInput, encoder *v2.Encoder) error { // encode using rest encoder utility if err := encoder.SetURI("api_Key").String(*input.ApiKey); err != nil { @@ -41,6 +45,8 @@ func MarshalGetApiKeyInputShapeAWSREST(input *types.GetApiKeyInput, encoder *v2. encoder.Encode() return nil } + +// MarshalGetApiKeyInputShapeAWSJSON is a stand alone function used to marshal the json body func MarshalGetApiKeyInputShapeAWSJSON(v *types.GetApiKeyInput, r *aws.Request) error { // delegate to reflection based marshaling if t := rest.PayloadType(r.Params); t == "structure" || t == "" { @@ -50,7 +56,7 @@ func MarshalGetApiKeyInputShapeAWSJSON(v *types.GetApiKeyInput, r *aws.Request) } // GetNamedBuildHandler returns a Named Build Handler for an operation marshal function -func (m ProtoGetApiKeyMarshaler) GetNamedBuildHandler() aws.NamedHandler { +func (m ProtoGetAPIKeyMarshaler) GetNamedBuildHandler() aws.NamedHandler { const BuildHandler = "ProtoGetApiKey.BuildHandler" return aws.NamedHandler{ Name: BuildHandler, diff --git a/service/apigateway/protoGetAPIKeyRequest_test.go b/service/apigateway/protoGetAPIKeyRequest_test.go index 566f41a126e..af1a4dde0fe 100644 --- a/service/apigateway/protoGetAPIKeyRequest_test.go +++ b/service/apigateway/protoGetAPIKeyRequest_test.go @@ -2,7 +2,6 @@ package apigateway_test import ( "context" - "fmt" "testing" "github.com/aws/aws-sdk-go-v2/aws" @@ -23,14 +22,13 @@ func TestProtoGetApiKeyRequest_Diff(t *testing.T) { request := svc.GetApiKeyRequest(&input) _, err := request.Send(context.TODO()) if err != nil { - fmt.Println(err) + t.Error(err) } - prototypeRequest := svc.ProtoGetApiKeyRequest(&input) + prototypeRequest := svc.ProtoGetAPIKeyRequest(&input) _, err = prototypeRequest.Send(context.TODO()) - if err != nil { - fmt.Println(err) + t.Error(err) } if diff := cmp.Diff(request.HTTPRequest.Header, prototypeRequest.HTTPRequest.Header); diff != "" { diff --git a/service/apigateway/proto_api_op_GetApiKey.go b/service/apigateway/proto_api_op_GetApiKey.go index 8bb3a61ba50..9a28103e108 100644 --- a/service/apigateway/proto_api_op_GetApiKey.go +++ b/service/apigateway/proto_api_op_GetApiKey.go @@ -9,22 +9,22 @@ import ( "github.com/aws/aws-sdk-go-v2/service/apigateway/types" ) -const protoOpGetApiKey = "GetApiKey" +const protoOpGetAPIKey = "GetApiKey" -// ProtoGetApiKeyRequest returns a request value for making API operation for +// ProtoGetAPIKeyRequest returns a request value for making API operation for // Amazon API Gateway. // // Gets information about the current ApiKey resource. // -// // Example sending a request using ProtoGetApiKeyRequest. -// req := client.ProtoGetApiKeyRequest(params) +// // Example sending a request using ProtoGetAPIKeyRequest. +// req := client.ProtoGetAPIKeyRequest(params) // resp, err := req.Send(context.TODO()) // if err == nil { // fmt.Println(resp) // } -func (c *Client) ProtoGetApiKeyRequest(input *types.GetApiKeyInput) ProtoGetApiKeyRequest { +func (c *Client) ProtoGetAPIKeyRequest(input *types.GetApiKeyInput) ProtoGetAPIKeyRequest { op := &aws.Operation{ - Name: protoOpGetApiKey, + Name: protoOpGetAPIKey, HTTPMethod: "GET", HTTPPath: "/apikeys/{api_Key}", } @@ -35,27 +35,27 @@ func (c *Client) ProtoGetApiKeyRequest(input *types.GetApiKeyInput) ProtoGetApiK req := c.newRequest(op, input, &types.GetApiKeyOutput{}) // swap existing build handler on svc, with a new named build handler - req.Handlers.Build.Swap(restjson.BuildHandler.Name, awsrestjson.ProtoGetApiKeyMarshaler{Input: input}.GetNamedBuildHandler()) - return ProtoGetApiKeyRequest{Request: req, Input: input, Copy: c.ProtoGetApiKeyRequest} + req.Handlers.Build.Swap(restjson.BuildHandler.Name, awsrestjson.ProtoGetAPIKeyMarshaler{Input: input}.GetNamedBuildHandler()) + return ProtoGetAPIKeyRequest{Request: req, Input: input, Copy: c.ProtoGetAPIKeyRequest} } -// ProtoGetApiKeyRequest is the request type for the +// ProtoGetAPIKeyRequest is the request type for the // GetApiKey API operation. -type ProtoGetApiKeyRequest struct { +type ProtoGetAPIKeyRequest struct { *aws.Request Input *types.GetApiKeyInput - Copy func(*types.GetApiKeyInput) ProtoGetApiKeyRequest + Copy func(*types.GetApiKeyInput) ProtoGetAPIKeyRequest } // Send marshals and sends the GetApiKey API request. -func (r ProtoGetApiKeyRequest) Send(ctx context.Context) (*ProtoGetApiKeyResponse, error) { +func (r ProtoGetAPIKeyRequest) Send(ctx context.Context) (*ProtoGetAPIKeyResponse, error) { r.Request.SetContext(ctx) err := r.Request.Send() if err != nil { return nil, err } - resp := &ProtoGetApiKeyResponse{ + resp := &ProtoGetAPIKeyResponse{ GetApiKeyOutput: r.Request.Data.(*types.GetApiKeyOutput), response: &aws.Response{Request: r.Request}, } @@ -63,9 +63,9 @@ func (r ProtoGetApiKeyRequest) Send(ctx context.Context) (*ProtoGetApiKeyRespons return resp, nil } -// ProtoGetApiKeyResponse is the response type for the +// ProtoGetAPIKeyResponse is the response type for the // GetApiKey API operation. -type ProtoGetApiKeyResponse struct { +type ProtoGetAPIKeyResponse struct { *types.GetApiKeyOutput response *aws.Response @@ -73,6 +73,6 @@ type ProtoGetApiKeyResponse struct { // SDKResponseMetdata returns the response metadata for the // GetApiKey request. -func (r *ProtoGetApiKeyResponse) SDKResponseMetdata() *aws.Response { +func (r *ProtoGetAPIKeyResponse) SDKResponseMetdata() *aws.Response { return r.response } diff --git a/service/s3/internal/awsrestxml/marshal.go b/service/s3/internal/awsrestxml/marshal.go new file mode 100644 index 00000000000..ad0adef5535 --- /dev/null +++ b/service/s3/internal/awsrestxml/marshal.go @@ -0,0 +1,105 @@ +package awsrestxml + +import ( + "log" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/private/protocol" + v2 "github.com/aws/aws-sdk-go-v2/private/protocol/rest/v2" + "github.com/aws/aws-sdk-go-v2/service/s3/types" +) + +// ProtoPutObjectMarshaler defines marshaler for ProtoPutObject operation +type ProtoPutObjectMarshaler struct { + Input *types.PutObjectInput +} + +// Marshal Operation is the top level method used within a handler stack to marshal an operation +// This method calls appropriate marshal shape functions as per the input shape and protocol used by the service. +func (m ProtoPutObjectMarshaler) MarshalOperation(r *aws.Request) { + var err error + encoder := v2.NewEncoder(r.HTTPRequest) + + err = MarshalPutObjectInputShapeAWSREST(m.Input, encoder) + if err != nil { + r.Error = err + } + + // since body payloadtype here is blob + if err = MarshalPutObjectInputShapeAWSXML(r, m.Input); err != nil { + r.Error = err + } +} + +// MarshalPutObjectInputShapeAWSREST is a stand alone function used to marshal the HTTP bindings a input shape. +// This method uses the rest encoder utility +func MarshalPutObjectInputShapeAWSREST(input *types.PutObjectInput, encoder *v2.Encoder) error { + // Encoding shapes with location `headers` + marshalShapeMapForHeaders(encoder, "x-amz-meta-", input.Metadata) + // Encoding shapes with location `header` + encoder.AddHeader("Cache-Control").String(*input.CacheControl) + encoder.AddHeader("Content-Disposition").String(*input.ContentDisposition) + encoder.AddHeader("Content-Language").String(*input.ContentLanguage) + encoder.AddHeader("Content-Length").Integer(*input.ContentLength) + encoder.AddHeader("Content-Md5").String(*input.ContentMD5) + encoder.AddHeader("Content-Type").String(*input.ContentType) + encoder.AddHeader("x-amz-acl").String(string(input.ACL)) + encoder.AddHeader("x-amz-grant-full-control").String(*input.GrantFullControl) + encoder.AddHeader("x-amz-grant-read").String(*input.GrantRead) + encoder.AddHeader("x-amz-grant-read-acp").String(*input.GrantReadACP) + encoder.AddHeader("x-amz-grant-write-acp").String(*input.GrantWriteACP) + encoder.AddHeader("x-amz-object-lock-legal-hold").String(string(input.ObjectLockLegalHoldStatus)) + encoder.AddHeader("x-amz-object-lock-mode").String(string(input.ObjectLockMode)) + encoder.AddHeader("x-amz-tagging").String(*input.Tagging) + encoder.AddHeader("x-amz-request-payer").String(string(input.RequestPayer)) + encoder.AddHeader("x-amz-server-side-encryption-context").String(*input.SSEKMSEncryptionContext) + encoder.AddHeader("x-amz-server-side-encryption-aws-kms-key-id").String(*input.SSEKMSKeyId) + encoder.AddHeader("x-amz-server-side-encryption-customer-key-MD5").String(*input.SSECustomerKeyMD5) + encoder.AddHeader("x-amz-server-side-encryption-customer-algorithm").String(*input.SSECustomerAlgorithm) + encoder.AddHeader("x-amz-website-redirect-location").String(*input.WebsiteRedirectLocation) + encoder.AddHeader("x-amz-storage-class").String(string(input.StorageClass)) + encoder.AddHeader("x-amz-server-side-encryption").String(string(input.ServerSideEncryption)) + if err := encoder.AddHeader("Expires").Time(*input.Expires, protocol.RFC822TimeFormatName); err != nil { + log.Fatalf("Failed to encode header for shape Expires: \n \t %v", err) + } + if err := encoder.AddHeader("x-amz-object-lock-retain-until-date").Time(*input.ObjectLockRetainUntilDate, protocol.ISO8601TimeFormatName); err != nil { + log.Fatalf("Failed to encode header for shape Expires: \n \t %v", err) + } + // Encoding shapes with location `uri` + if err := encoder.SetURI("Bucket").String(*input.Bucket); err != nil { + log.Fatalf("Failed to encode URI, \n\t %v\n", err) + } + if err := encoder.SetURI("Key").String(*input.Key); err != nil { + log.Fatalf("Failed to encode URI, \n\t %v\n", err) + } + // encode using rest encoder utility + encoder.Encode() + return nil +} + +// MarshalPutObjectInputShapeAWSXML is a stand alone function used to marshal the xml payload +// This should be generated according to the payload type for rest-xml protocol +func MarshalPutObjectInputShapeAWSXML(r *aws.Request, input *types.PutObjectInput) error { + if input.Body != nil { + r.SetReaderBody(input.Body) + } + return nil +} + +// marshalShapeMapForHeaders is marshal function that takes in a map[string]string as an input along with an encoder +// and location Name which should be used to marshal the shape with location headers. +func marshalShapeMapForHeaders(encoder *v2.Encoder, locationName string, input map[string]string) { + headerObject := encoder.Headers(locationName) + for k, v := range input { + headerObject.AddHeader(k).String(v) + } +} + +// GetNamedBuildHandler returns a Named Build Handler for an operation marshal function +func (m ProtoPutObjectMarshaler) GetNamedBuildHandler() aws.NamedHandler { + const BuildHandler = "ProtoPutBucket.BuildHandler" + return aws.NamedHandler{ + Name: BuildHandler, + Fn: m.MarshalOperation, + } +} diff --git a/service/s3/proto_api_op_PutObject.go b/service/s3/proto_api_op_PutObject.go new file mode 100644 index 00000000000..53a7dbd2241 --- /dev/null +++ b/service/s3/proto_api_op_PutObject.go @@ -0,0 +1,249 @@ +package s3 + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/private/protocol/restxml" + "github.com/aws/aws-sdk-go-v2/service/s3/internal/awsrestxml" + "github.com/aws/aws-sdk-go-v2/service/s3/types" +) + +const protoOpPutObject = "PutObject" + +// PutObjectRequest returns a request value for making API operation for +// Amazon Simple Storage Service. +// +// Adds an object to a bucket. You must have WRITE permissions on a bucket to +// add an object to it. +// +// Amazon S3 never adds partial objects; if you receive a success response, +// Amazon S3 added the entire object to the bucket. +// +// Amazon S3 is a distributed system. If it receives multiple write requests +// for the same object simultaneously, it overwrites all but the last object +// written. Amazon S3 does not provide object locking; if you need this, make +// sure to build it into your application layer or use versioning instead. +// +// To ensure that data is not corrupted traversing the network, use the Content-MD5 +// header. When you use this header, Amazon S3 checks the object against the +// provided MD5 value and, if they do not match, returns an error. Additionally, +// you can calculate the MD5 while putting an object to Amazon S3 and compare +// the returned ETag to the calculated MD5 value. +// +// To configure your application to send the request headers before sending +// the request body, use the 100-continue HTTP status code. For PUT operations, +// this helps you avoid sending the message body if the message is rejected +// based on the headers (for example, because authentication fails or a redirect +// occurs). For more information on the 100-continue HTTP status code, see Section +// 8.2.3 of http://www.ietf.org/rfc/rfc2616.txt (http://www.ietf.org/rfc/rfc2616.txt). +// +// You can optionally request server-side encryption. With server-side encryption, +// Amazon S3 encrypts your data as it writes it to disks in its data centers +// and decrypts the data when you access it. You have the option to provide +// your own encryption key or use AWS-managed encryption keys. For more information, +// see Using Server-Side Encryption (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html). +// +// Access Permissions +// +// You can optionally specify the accounts or groups that should be granted +// specific permissions on the new object. There are two ways to grant the permissions +// using the request headers: +// +// * Specify a canned ACL with the x-amz-acl request header. For more information, +// see Canned ACL (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL). +// +// * Specify access permissions explicitly with the x-amz-grant-read, x-amz-grant-read-acp, +// x-amz-grant-write-acp, and x-amz-grant-full-control headers. These parameters +// map to the set of permissions that Amazon S3 supports in an ACL. For more +// information, see Access Control List (ACL) Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html). +// +// You can use either a canned ACL or specify access permissions explicitly. +// You cannot do both. +// +// Server-Side- Encryption-Specific Request Headers +// +// You can optionally tell Amazon S3 to encrypt data at rest using server-side +// encryption. Server-side encryption is for data encryption at rest. Amazon +// S3 encrypts your data as it writes it to disks in its data centers and decrypts +// it when you access it. The option you use depends on whether you want to +// use AWS-managed encryption keys or provide your own encryption key. +// +// * Use encryption keys managed Amazon S3 or customer master keys (CMKs) +// stored in AWS Key Management Service (KMS) – If you want AWS to manage +// the keys used to encrypt data, specify the following headers in the request. +// x-amz-server-side​-encryption x-amz-server-side-encryption-aws-kms-key-id +// x-amz-server-side-encryption-context If you specify x-amz-server-side-encryption:aws:kms, +// but don't provide x-amz-server-side- encryption-aws-kms-key-id, Amazon +// S3 uses the AWS managed CMK in AWS KMS to protect the data. All GET and +// PUT requests for an object protected by AWS KMS fail if you don't make +// them with SSL or by using SigV4. For more information on Server-Side Encryption +// with CMKs stored in AWS KMS (SSE-KMS), see Protecting Data Using Server-Side +// Encryption with CMKs stored in AWS (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html). +// +// * Use customer-provided encryption keys – If you want to manage your +// own encryption keys, provide all the following headers in the request. +// x-amz-server-side​-encryption​-customer-algorithm x-amz-server-side​-encryption​-customer-key +// x-amz-server-side​-encryption​-customer-key-MD5 For more information +// on Server-Side Encryption with CMKs stored in KMS (SSE-KMS), see Protecting +// Data Using Server-Side Encryption with CMKs stored in AWS KMS (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html). +// +// Access-Control-List (ACL)-Specific Request Headers +// +// You also can use the following access control–related headers with this +// operation. By default, all objects are private. Only the owner has full access +// control. When adding a new object, you can grant permissions to individual +// AWS accounts or to predefined groups defined by Amazon S3. These permissions +// are then added to the Access Control List (ACL) on the object. For more information, +// see Using ACLs (https://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html). +// With this operation, you can grant access permissions using one of the following +// two methods: +// +// * Specify a canned ACL (x-amz-acl) — Amazon S3 supports a set of predefined +// ACLs, known as canned ACLs. Each canned ACL has a predefined set of grantees +// and permissions. For more information, see Canned ACL (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL). +// +// * Specify access permissions explicitly — To explicitly grant access +// permissions to specific AWS accounts or groups, use the following headers. +// Each header maps to specific permissions that Amazon S3 supports in an +// ACL. For more information, see Access Control List (ACL) Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html). +// In the header, you specify a list of grantees who get the specific permission. +// To grant permissions explicitly use: x-amz-grant-read x-amz-grant-write +// x-amz-grant-read-acp x-amz-grant-write-acp x-amz-grant-full-control You +// specify each grantee as a type=value pair, where the type is one of the +// following: emailAddress – if the value specified is the email address +// of an AWS account Using email addresses to specify a grantee is only supported +// in the following AWS Regions: US East (N. Virginia) US West (N. California) +// US West (Oregon) Asia Pacific (Singapore) Asia Pacific (Sydney) Asia Pacific +// (Tokyo) EU (Ireland) South America (São Paulo) For a list of all the +// Amazon S3 supported regions and endpoints, see Regions and Endpoints (https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) +// in the AWS General Reference id – if the value specified is the canonical +// user ID of an AWS account uri – if you are granting permissions to a +// predefined group For example, the following x-amz-grant-read header grants +// the AWS accounts identified by email addresses permissions to read object +// data and its metadata: x-amz-grant-read: emailAddress="xyz@amazon.com", +// emailAddress="abc@amazon.com" +// +// Server-Side- Encryption-Specific Request Headers +// +// You can optionally tell Amazon S3 to encrypt data at rest using server-side +// encryption. Server-side encryption is for data encryption at rest. Amazon +// S3 encrypts your data as it writes it to disks in its data centers and decrypts +// it when you access it. The option you use depends on whether you want to +// use AWS-managed encryption keys or provide your own encryption key. +// +// * Use encryption keys managed by Amazon S3 or customer master keys (CMKs) +// stored in AWS Key Management Service (KMS) – If you want AWS to manage +// the keys used to encrypt data, specify the following headers in the request. +// x-amz-server-side​-encryption x-amz-server-side-encryption-aws-kms-key-id +// x-amz-server-side-encryption-context If you specify x-amz-server-side-encryption:aws:kms, +// but don't provide x-amz-server-side- encryption-aws-kms-key-id, Amazon +// S3 uses the default AWS KMS CMK to protect the data. All GET and PUT requests +// for an object protected by AWS KMS fail if you don't make them with SSL +// or by using SigV4. For more information on Server-Side Encryption with +// CMKs stored in AWS KMS (SSE-KMS), see Protecting Data Using Server-Side +// Encryption with CMKs stored in AWS KMS (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html). +// +// * Use customer-provided encryption keys – If you want to manage your +// own encryption keys, provide all the following headers in the request. +// If you use this feature, the ETag value that Amazon S3 returns in the +// response is not the MD5 of the object. x-amz-server-side​-encryption​-customer-algorithm +// x-amz-server-side​-encryption​-customer-key x-amz-server-side​-encryption​-customer-key-MD5 +// For more information on Server-Side Encryption with CMKs stored in AWS +// KMS (SSE-KMS), see Protecting Data Using Server-Side Encryption with CMKs +// stored in AWS KMS (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html). +// +// Storage Class Options +// +// By default, Amazon S3 uses the Standard storage class to store newly created +// objects. The Standard storage class provides high durability and high availability. +// You can specify other storage classes depending on the performance needs. +// For more information, see Storage Classes (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html) +// in the Amazon Simple Storage Service Developer Guide. +// +// Versioning +// +// If you enable versioning for a bucket, Amazon S3 automatically generates +// a unique version ID for the object being stored. Amazon S3 returns this ID +// in the response using the x-amz-version-id response header. If versioning +// is suspended, Amazon S3 always uses null as the version ID for the object +// stored. For more information about returning the versioning state of a bucket, +// see GetBucketVersioning. If you enable versioning for a bucket, when Amazon +// S3 receives multiple write requests for the same object simultaneously, it +// stores all of the objects. +// +// Related Resources +// +// * CopyObject +// +// * DeleteObject +// +// // Example sending a request using PutObjectRequest. +// req := client.ProtoPutObjectRequest(params) +// resp, err := req.Send(context.TODO()) +// if err == nil { +// fmt.Println(resp) +// } +// +// Please also see https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObject + +func (c *Client) ProtoPutObjectRequest(input *types.PutObjectInput) ProtoPutObjectRequest { + op := &aws.Operation{ + Name: protoOpPutObject, + HTTPMethod: "PUT", + HTTPPath: "/{Bucket}/{Key+}", + } + + if input == nil { + input = &types.PutObjectInput{} + } + + req := c.newRequest(op, input, &types.PutObjectOutput{}) + + // swap existing build handler on svc, with a new named build handler + req.Handlers.Build.Swap(restxml.BuildHandler.Name, + awsrestxml.ProtoPutObjectMarshaler{ + Input: input, + }.GetNamedBuildHandler(), + ) + + return ProtoPutObjectRequest{Request: req, Input: input, Copy: c.ProtoPutObjectRequest} +} + +// PutObjectRequest is the request type for the +// PutObject API operation. +type ProtoPutObjectRequest struct { + *aws.Request + Input *types.PutObjectInput + Copy func(*types.PutObjectInput) ProtoPutObjectRequest +} + +// Send marshals and sends the PutObject API request. +func (r ProtoPutObjectRequest) Send(ctx context.Context) (*ProtoPutObjectResponse, error) { + r.Request.SetContext(ctx) + err := r.Request.Send() + if err != nil { + return nil, err + } + + resp := &ProtoPutObjectResponse{ + PutObjectOutput: r.Request.Data.(*types.PutObjectOutput), + response: &aws.Response{Request: r.Request}, + } + + return resp, nil +} + +// ProtoPutObjectResponse is the response type for the +// ProtoPutObject API operation. +type ProtoPutObjectResponse struct { + *types.PutObjectOutput + + response *aws.Response +} + +// SDKResponseMetdata returns the response metadata for the +// PutObject request. +func (r *ProtoPutObjectResponse) SDKResponseMetdata() *aws.Response { + return r.response +} diff --git a/service/s3/proto_api_op_PutObject_test.go b/service/s3/proto_api_op_PutObject_test.go new file mode 100644 index 00000000000..3b417141a05 --- /dev/null +++ b/service/s3/proto_api_op_PutObject_test.go @@ -0,0 +1,76 @@ +package s3_test + +import ( + "context" + "testing" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/internal/awstesting/mock" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/s3/enums" + "github.com/aws/aws-sdk-go-v2/service/s3/types" + "github.com/google/go-cmp/cmp" +) + +func TestProtoPutObjectRequest_Diff(t *testing.T) { + svc := s3.New(mock.Config()) + + input := types.PutObjectInput{ + ACL: enums.ObjectCannedACLAuthenticatedRead, + Body: nil, + ContentLength: aws.Int64(0), + Bucket: aws.String("mock bucket"), + CacheControl: aws.String("mock cache control"), + ContentDisposition: aws.String("mock content disposition"), + ContentLanguage: aws.String("english"), + ContentMD5: aws.String("mock MD5"), + ContentType: aws.String("mock content type"), + Expires: aws.Time(time.Now()), + GrantFullControl: aws.String("mock full control"), + GrantRead: aws.String("mock read grant"), + GrantReadACP: aws.String("mock acp read"), + GrantWriteACP: aws.String("mock write acp"), + Key: aws.String("mock key"), + Metadata: map[string]string{ + "mockMetaKey01": "mockMetaValue01", + "mockMetaKey02": "mockMetaValue02", + "mockMetaKey03": "mockMetaValue03", + }, + ObjectLockLegalHoldStatus: enums.ObjectLockLegalHoldStatusOn, + ObjectLockMode: enums.ObjectLockModeCompliance, + ObjectLockRetainUntilDate: aws.Time(time.Now()), + RequestPayer: enums.RequestPayerRequester, + SSECustomerAlgorithm: aws.String("mock sse cust Algo"), + SSECustomerKey: nil, + SSECustomerKeyMD5: aws.String("mock sse MD5"), + SSEKMSEncryptionContext: aws.String("mock encryption content"), + SSEKMSKeyId: aws.String("mock ssekmskey id"), + ServerSideEncryption: enums.ServerSideEncryptionAes256, + StorageClass: enums.StorageClassGlacier, + Tagging: aws.String("mock tagging"), + WebsiteRedirectLocation: aws.String("mock redirection"), + } + + // request created for existing put object request + request := svc.PutObjectRequest(&input) + _, err := request.Send(context.TODO()) + if err != nil { + t.Error(err) + } + + // request created for prototyped put object request + prototypeRequest := svc.ProtoPutObjectRequest(&input) + _, err = prototypeRequest.Send(context.TODO()) + if err != nil { + t.Error(err) + } + + if diff := cmp.Diff(request.HTTPRequest.Header, prototypeRequest.HTTPRequest.Header); diff != "" { + t.Errorf("Found diff: %v", diff) + } + + if diff := cmp.Diff(request.HTTPRequest.URL, prototypeRequest.HTTPRequest.URL); diff != "" { + t.Errorf("Found diff: %v", diff) + } +}