Skip to content

Commit

Permalink
remove content type header from streaming operations if payload is em…
Browse files Browse the repository at this point in the history
…pty or nil
  • Loading branch information
skotambkar committed Dec 11, 2020
1 parent 810f557 commit 54732ce
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 4 deletions.
42 changes: 42 additions & 0 deletions aws/middleware/content_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package middleware

import (
"context"
"fmt"
"github.com/awslabs/smithy-go/middleware"
smithyhttp "github.com/awslabs/smithy-go/transport/http"
)

// removeContentTypeHeader is a build middleware that removes
// content type header if content-length header is unset or
// is set to zero,
type removeContentTypeHeader struct {
}

// ID the name of the middleware.
func (m *removeContentTypeHeader) ID() string {
return "RemoveContentTypeHeader"
}

// HandleBuild adds or appends the constructed user agent to the request.
func (m *removeContentTypeHeader) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) (
out middleware.BuildOutput, metadata middleware.Metadata, err error,
) {
req, ok := in.Request.(*smithyhttp.Request)
if !ok {
return out, metadata, fmt.Errorf("unknown transport type %T", in)
}

// remove contentTypeHeader when content-length is zero
if req.ContentLength == 0 {
req.Header.Del("content-type")
}

return next.HandleBuild(ctx, in)
}

// RemoveContentTypeHeader removes content-type header if
// content length is unset or equal to zero.
func RemoveContentTypeHeader(stack *middleware.Stack) error {
return stack.Build.Add(&removeContentTypeHeader{}, middleware.After)
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ private static final String addAsUnsignedPayloadName(String operationName) {
return String.format("add%sPayloadAsUnsigned", operationName);
}

private static final Symbol removeContentTypeHeader = SymbolUtils.createValueSymbolBuilder(
"RemoveContentTypeHeader", AwsGoDependency.AWS_MIDDLEWARE
).build();

// build pointable symbols
private static Symbol buildSymbol(String name, boolean exported) {
if (!exported) {
Expand Down Expand Up @@ -255,6 +259,20 @@ private void writePresignOperationFunction(
.getAddOperationMiddlewareFuncName(operationSymbol));
writer.write("c.$L,", CONVERT_TO_PRESIGN_MIDDLEWARE_NAME);

// we should remove Content-Type header if input is a stream and
// payload is empty/nil stream.
if (operationInputShape.members().stream().anyMatch(memberShape -> {
return memberShape.getMemberTrait(model, StreamingTrait.class).isPresent();
})) {
writer.addUseImports(SmithyGoDependency.SMITHY_MIDDLEWARE);
writer.addUseImports(AwsGoDependency.AWS_MIDDLEWARE);

writer.openBlock("func(stack *middleware.Stack, options Options) error {", "}," ,
() -> {
writer.write("return $T(stack)", removeContentTypeHeader);
});
}

// s3 needs to add a middleware to switch to using unsigned payload .
if (isS3ServiceShape(model, serviceShape)) {
writer.write("$L,", addAsUnsignedPayloadName(operationSymbol.getName()));
Expand Down
6 changes: 2 additions & 4 deletions service/internal/integrationtest/s3/presign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,8 @@ func TestInteg_PresignURL(t *testing.T) {
expectedSignedHeader: http.Header{},
},
"empty-body": {
body: bytes.NewReader([]byte("")),
expectedSignedHeader: http.Header{
"content-type": {"application/octet-stream"},
},
body: bytes.NewReader([]byte("")),
expectedSignedHeader: http.Header{},
},
}

Expand Down
3 changes: 3 additions & 0 deletions service/s3/api_op_PutObject.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 54732ce

Please sign in to comment.