support connection close header (#2672)

This commit is contained in:
Victor Vazquez 2021-07-27 10:03:56 -07:00 committed by GitHub
parent c8a45ad7ac
commit 0567145212
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 65 additions and 2 deletions

View File

@ -3,12 +3,15 @@
## 1.2.0-beta.1 (Unreleased)
### Features Added
- Added `Azure::Core::IO::ProgressBodyStream` type that wraps an existing BodyStream based type stream and reports progress via callback when the stream position is updated.
- Added `Azure::Core::IO::ProgressBodyStream` type that wraps an existing BodyStream based type stream and reports progress via callback when the stream position is updated.
### Breaking Changes
### Bugs Fixed
- [2647](https://github.com/Azure/azure-sdk-for-cpp/issues/2647) Make the curl transport adapter to check the connection close header.
### Other Changes
## 1.1.0 (2021-07-02)

View File

@ -714,7 +714,20 @@ void CurlSession::ReadStatusLineAndHeadersFromRawResponse(
}
// headers are already lowerCase at this point
auto headers = this->m_response->GetHeaders();
auto const& headers = this->m_response->GetHeaders();
// Check if server has return the connection header. This header can be used to stop re-using the
// connection. The `Iot Edge Blob Storage Module` is known to return this after some time re-using
// the same http secured channel.
auto connectionHeader = headers.find("connection");
if (connectionHeader != headers.end())
{
if (connectionHeader->second == "close")
{
// Use connection shut-down so it won't be moved it back to the connection pool.
m_connection->Shutdown();
}
}
auto isContentLengthHeaderInResponse = headers.find("content-length");
if (isContentLengthHeaderInResponse != headers.end())

View File

@ -29,6 +29,7 @@
namespace Azure { namespace Core { namespace Test {
class CurlConnectionPool_connectionPoolTest_Test;
class CurlConnectionPool_uniquePort_Test;
class CurlConnectionPool_connectionClose_Test;
}}} // namespace Azure::Core::Test
#endif
@ -46,6 +47,7 @@ namespace Azure { namespace Core { namespace Http { namespace _detail {
// Give access to private to this tests class
friend class Azure::Core::Test::CurlConnectionPool_connectionPoolTest_Test;
friend class Azure::Core::Test::CurlConnectionPool_uniquePort_Test;
friend class Azure::Core::Test::CurlConnectionPool_connectionClose_Test;
#endif
public:

View File

@ -554,5 +554,45 @@ namespace Azure { namespace Core { namespace Test {
}
}
TEST(CurlConnectionPool, connectionClose)
{
/// When getting the header connection: close from an HTTP response, the connection should not
/// be moved back to the pool.
{
std::lock_guard<std::mutex> lock(
CurlConnectionPool::g_curlConnectionPool.ConnectionPoolMutex);
CurlConnectionPool::g_curlConnectionPool.ConnectionPoolIndex.clear();
// Make sure there are nothing in the pool
EXPECT_EQ(CurlConnectionPool::g_curlConnectionPool.ConnectionPoolIndex.size(), 0);
}
// Use the same request for all connections.
Azure::Core::Http::Request req(
Azure::Core::Http::HttpMethod::Get, Azure::Core::Url(AzureSdkHttpbinServer::Headers()));
// Server will return this header back
req.SetHeader("connection", "close");
{
// Create a pipeline to send the request and dispose after it.
Azure::Core::Http::_internal::HttpPipeline pipeline({}, "test", "test", {}, {});
auto response = pipeline.Send(req, Azure::Core::Context::ApplicationContext);
EXPECT_PRED2(
[](Azure::Core::Http::HttpStatusCode a, Azure::Core::Http::HttpStatusCode b) {
return a == b;
},
response->GetStatusCode(),
Azure::Core::Http::HttpStatusCode::Ok);
}
// Check that after the connection is gone, it is moved back to the pool
{
std::lock_guard<std::mutex> lock(
CurlConnectionPool::g_curlConnectionPool.ConnectionPoolMutex);
EXPECT_EQ(
Azure::Core::Http::_detail::CurlConnectionPool::g_curlConnectionPool.ConnectionPoolIndex
.size(),
0);
}
}
#endif
}}} // namespace Azure::Core::Test

View File

@ -31,6 +31,11 @@ namespace Azure { namespace Core { namespace Test {
return std::string(_detail::AzureSdkHttpbinServerSchema) + "://"
+ std::string(_detail::AzureSdkHttpbinServer) + "/get";
}
inline static std::string Headers()
{
return std::string(_detail::AzureSdkHttpbinServerSchema) + "://"
+ std::string(_detail::AzureSdkHttpbinServer) + "/headers";
}
inline static std::string WithPort()
{
return std::string(_detail::AzureSdkHttpbinServerSchema) + "://"