Skip to content

Commit

Permalink
fix: Omit the Content-Type header for requests without bodies
Browse files Browse the repository at this point in the history
  • Loading branch information
ashovlin committed Jun 10, 2024
1 parent 1baa759 commit 526b6a2
Show file tree
Hide file tree
Showing 15 changed files with 667 additions and 63 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"core": {
"changeLogMessages": [
"Omit the Content-Type header for requests without bodies"
],
"type": "patch",
"updateMinimum": true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@
"errors":[],
"documentation":"<p> Request without a body </p>"
},
"NoPayloadPost":{
"name":"NoPayloadPost",
"http":{
"method":"POST",
"requestUri":"/no-payload"
},
"input":{"shape":"NoPayloadRequest"},
"output":{"shape":"NoPayloadResult"},
"errors":[],
"documentation":"<p> A POST request without a body, for verifying that we don't set a Content-Type even though a POST could have a body </p>"
},
"TestPayload":{
"name":"TestPayload",
"http":{
Expand Down
25 changes: 10 additions & 15 deletions sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/Marshaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public override void InvokeSync(IExecutionContext executionContext)
public override System.Threading.Tasks.Task<T> InvokeAsync<T>(IExecutionContext executionContext)
{
PreInvoke(executionContext);
return base.InvokeAsync<T>(executionContext);
return base.InvokeAsync<T>(executionContext);
}

#elif AWS_APM_API
Expand Down Expand Up @@ -81,20 +81,15 @@ protected static void PreInvoke(IExecutionContext executionContext)
requestContext.Request = requestContext.Marshaller.Marshall(requestContext.OriginalRequest);
requestContext.Request.AuthenticationRegion = requestContext.ClientConfig.AuthenticationRegion;

#if NETSTANDARD
var method = requestContext.Request.HttpMethod.ToUpperInvariant();
#else
var method = requestContext.Request.HttpMethod.ToUpper(CultureInfo.InvariantCulture);
#endif
if (method != "GET" && method != "DELETE" && method != "HEAD")
// If the request has a body and its request-specific marshaller didn't already
// set Content-Type, follow our existing fallback logic
if (requestContext.Request.HasRequestBody() &&
!requestContext.Request.Headers.ContainsKey(HeaderKeys.ContentTypeHeader))
{
if (!requestContext.Request.Headers.ContainsKey(HeaderKeys.ContentTypeHeader))
{
if (requestContext.Request.UseQueryString)
requestContext.Request.Headers[HeaderKeys.ContentTypeHeader] = "application/x-amz-json-1.0";
else
requestContext.Request.Headers[HeaderKeys.ContentTypeHeader] = AWSSDKUtils.UrlEncodedContent;
}
if (requestContext.Request.UseQueryString)
requestContext.Request.Headers[HeaderKeys.ContentTypeHeader] = "application/x-amz-json-1.0";
else
requestContext.Request.Headers[HeaderKeys.ContentTypeHeader] = AWSSDKUtils.UrlEncodedContent;
}

SetRecursionDetectionHeader(requestContext.Request.Headers);
Expand All @@ -108,7 +103,7 @@ protected static void PreInvoke(IExecutionContext executionContext)
private static void SetRecursionDetectionHeader(IDictionary<string, string> headers)
{
if (!headers.ContainsKey(HeaderKeys.XAmznTraceIdHeader))
{
{
var lambdaFunctionName = Environment.GetEnvironmentVariable(EnvironmentVariables.AWS_LAMBDA_FUNCTION_NAME);
var amznTraceId = Environment.GetEnvironmentVariable(EnvironmentVariables._X_AMZN_TRACE_ID);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

/*
* Do not modify this file. This file is generated from the rest-json-test-2016-04-12.normal.json service model.
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml.Serialization;

using Amazon.RestJsonTest.Model;
using Amazon.Runtime;
using Amazon.Runtime.Internal;
using Amazon.Runtime.Internal.Transform;
using Amazon.Runtime.Internal.Util;
using ThirdParty.Json.LitJson;

#pragma warning disable CS0612,CS0618
namespace Amazon.RestJsonTest.Model.Internal.MarshallTransformations
{
/// <summary>
/// NoPayloadPost Request Marshaller
/// </summary>
public class NoPayloadPostRequestMarshaller : IMarshaller<IRequest, NoPayloadPostRequest> , IMarshaller<IRequest,AmazonWebServiceRequest>
{
/// <summary>
/// Marshaller the request object to the HTTP request.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public IRequest Marshall(AmazonWebServiceRequest input)
{
return this.Marshall((NoPayloadPostRequest)input);
}

/// <summary>
/// Marshaller the request object to the HTTP request.
/// </summary>
/// <param name="publicRequest"></param>
/// <returns></returns>
public IRequest Marshall(NoPayloadPostRequest publicRequest)
{
IRequest request = new DefaultRequest(publicRequest, "Amazon.RestJsonTest");
request.Headers[Amazon.Util.HeaderKeys.XAmzApiVersion] = "2021-05-13";
request.HttpMethod = "POST";

request.ResourcePath = "/no-payload";

if (publicRequest.IsSetTestId())
{
request.Headers["x-amz-test-id"] = publicRequest.TestId;
}

return request;
}
private static NoPayloadPostRequestMarshaller _instance = new NoPayloadPostRequestMarshaller();

internal static NoPayloadPostRequestMarshaller GetInstance()
{
return _instance;
}

/// <summary>
/// Gets the singleton.
/// </summary>
public static NoPayloadPostRequestMarshaller Instance
{
get
{
return _instance;
}
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

/*
* Do not modify this file. This file is generated from the rest-json-test-2016-04-12.normal.json service model.
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
using System.Xml.Serialization;

using Amazon.RestJsonTest.Model;
using Amazon.Runtime;
using Amazon.Runtime.Internal;
using Amazon.Runtime.Internal.Transform;
using Amazon.Runtime.Internal.Util;
using ThirdParty.Json.LitJson;

#pragma warning disable CS0612,CS0618
namespace Amazon.RestJsonTest.Model.Internal.MarshallTransformations
{
/// <summary>
/// Response Unmarshaller for NoPayloadPost operation
/// </summary>
public class NoPayloadPostResponseUnmarshaller : JsonResponseUnmarshaller
{
/// <summary>
/// Unmarshaller the response from the service to the response class.
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override AmazonWebServiceResponse Unmarshall(JsonUnmarshallerContext context)
{
NoPayloadPostResponse response = new NoPayloadPostResponse();

context.Read();
int targetDepth = context.CurrentDepth;
while (context.ReadAtDepth(targetDepth))
{
if (context.TestExpression("testId", targetDepth))
{
var unmarshaller = StringUnmarshaller.Instance;
response.TestId = unmarshaller.Unmarshall(context);
continue;
}
}

return response;
}

/// <summary>
/// Unmarshaller error response to exception.
/// </summary>
/// <param name="context"></param>
/// <param name="innerException"></param>
/// <param name="statusCode"></param>
/// <returns></returns>
public override AmazonServiceException UnmarshallException(JsonUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode)
{
var errorResponse = JsonErrorResponseUnmarshaller.GetInstance().Unmarshall(context);
errorResponse.InnerException = innerException;
errorResponse.StatusCode = statusCode;

var responseBodyBytes = context.GetResponseBodyBytes();

using (var streamCopy = new MemoryStream(responseBodyBytes))
using (var contextCopy = new JsonUnmarshallerContext(streamCopy, false, null))
{
}
return new AmazonRestJsonTestException(errorResponse.Message, errorResponse.InnerException, errorResponse.Type, errorResponse.Code, errorResponse.RequestId, errorResponse.StatusCode);
}

private static NoPayloadPostResponseUnmarshaller _instance = new NoPayloadPostResponseUnmarshaller();

internal static NoPayloadPostResponseUnmarshaller GetInstance()
{
return _instance;
}

/// <summary>
/// Gets the singleton.
/// </summary>
public static NoPayloadPostResponseUnmarshaller Instance
{
get
{
return _instance;
}
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

/*
* Do not modify this file. This file is generated from the rest-json-test-2016-04-12.normal.json service model.
*/
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Text;
using System.IO;
using System.Net;

using Amazon.Runtime;
using Amazon.Runtime.Internal;

#pragma warning disable CS0612,CS0618,CS1570
namespace Amazon.RestJsonTest.Model
{
/// <summary>
/// Container for the parameters to the NoPayloadPost operation.
/// A POST request without a body, for verifying that we don't set a Content-Type even
/// though a POST could have a body
/// </summary>
public partial class NoPayloadPostRequest : AmazonRestJsonTestRequest
{
private string _testId;

/// <summary>
/// Gets and sets the property TestId.
/// <para>
/// The unique ID for a test.
/// </para>
/// </summary>
[AWSProperty(Min=3, Max=8)]
public string TestId
{
get { return this._testId; }
set { this._testId = value; }
}

// Check to see if TestId property is set
internal bool IsSetTestId()
{
return !string.IsNullOrEmpty(this._testId);
}

}
}
Loading

0 comments on commit 526b6a2

Please sign in to comment.