diff --git a/sdk/core/azure-core/src/http/transport_policy.cpp b/sdk/core/azure-core/src/http/transport_policy.cpp index bf79cda4d..cc076b641 100644 --- a/sdk/core/azure-core/src/http/transport_policy.cpp +++ b/sdk/core/azure-core/src/http/transport_policy.cpp @@ -16,13 +16,19 @@ std::unique_ptr TransportPolicy::Send( * Call the transport and return */ auto response = m_transport->Send(ctx, request); - if (request. IsDownloadViaStream()) + auto statusCode = static_cast::type>( + response->GetStatusCode()); + + if (request.IsDownloadViaStream() && statusCode < 300) { // special case to return a response with BodyStream to read directly from socket + // Return only if response is valid (less than 300) return response; } // default behavior for all request is to download body content to Response // If ReadToEnd fail, retry policy will eventually call this again + // Using DownloadViaStream and getting an error code would also get to here to download error from + // body auto bodyStream = response->GetBodyStream(); response->SetBody(BodyStream::ReadToEnd(ctx, *bodyStream)); // BodyStream is moved out of response. This makes transport implementation to clean any active diff --git a/sdk/core/azure-core/test/ut/file_upload.cpp b/sdk/core/azure-core/test/ut/file_upload.cpp index 7e62c4c87..eb44dc797 100644 --- a/sdk/core/azure-core/test/ut/file_upload.cpp +++ b/sdk/core/azure-core/test/ut/file_upload.cpp @@ -21,14 +21,16 @@ namespace Azure { namespace Core { namespace Test { constexpr int64_t c_fileSize = 1024 * 100; } - void TransportAdapter::checkResponseCode(Azure::Core::Http::HttpStatusCode code) + void TransportAdapter::checkResponseCode( + Azure::Core::Http::HttpStatusCode code, + Azure::Core::Http::HttpStatusCode expectedCode) { /* if (code != Azure::Core::Http::HttpStatusCode::Ok) { std::cout << static_cast::type>(code); return; } */ - EXPECT_TRUE(code == Azure::Core::Http::HttpStatusCode::Ok); + EXPECT_TRUE(code == expectedCode); } void TransportAdapter::CheckBodyFromBuffer( diff --git a/sdk/core/azure-core/test/ut/transport_adapter.cpp b/sdk/core/azure-core/test/ut/transport_adapter.cpp index 4ba644198..bb586b648 100644 --- a/sdk/core/azure-core/test/ut/transport_adapter.cpp +++ b/sdk/core/azure-core/test/ut/transport_adapter.cpp @@ -303,4 +303,22 @@ namespace Azure { namespace Core { namespace Test { } } + TEST_F(TransportAdapter, putWithStreamOnFail) + { + // point to bad address pah to generate server MethodNotAllowed error + std::string host("http://httpbin.org/get"); + + // PUT 1k + auto requestBodyVector = std::vector(1024, 'x'); + auto bodyRequest = Azure::Core::Http::MemoryBodyStream(requestBodyVector); + auto request + = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Put, host, &bodyRequest, true); + auto response = pipeline.Send(context, request); + checkResponseCode( + response->GetStatusCode(), Azure::Core::Http::HttpStatusCode::MethodNotAllowed); + auto expectedResponseBodySize = std::stoull(response->GetHeaders().at("content-length")); + + CheckBodyFromBuffer(*response, expectedResponseBodySize); + } + }}} // namespace Azure::Core::Test diff --git a/sdk/core/azure-core/test/ut/transport_adapter.hpp b/sdk/core/azure-core/test/ut/transport_adapter.hpp index c58414e5f..4915d7724 100644 --- a/sdk/core/azure-core/test/ut/transport_adapter.hpp +++ b/sdk/core/azure-core/test/ut/transport_adapter.hpp @@ -28,7 +28,9 @@ namespace Azure { namespace Core { namespace Test { int64_t size, std::string expectedBody = std::string("")); - static void checkResponseCode(Azure::Core::Http::HttpStatusCode code); + static void checkResponseCode( + Azure::Core::Http::HttpStatusCode code, + Azure::Core::Http::HttpStatusCode expectedCode = Azure::Core::Http::HttpStatusCode::Ok); }; }}} // namespace Azure::Core::Test