handle server chunked response without number (#881)
This commit is contained in:
parent
1fa314f19e
commit
75c3f85ca6
@ -446,7 +446,18 @@ void CurlSession::ParseChunkSize(Context const& context)
|
||||
if (i > 1 && this->m_readBuffer[index] == '\n')
|
||||
{
|
||||
// get chunk size. Chunk size comes in Hex value
|
||||
this->m_chunkSize = static_cast<int64_t>(std::stoull(strChunkSize, nullptr, 16));
|
||||
try
|
||||
{
|
||||
this->m_chunkSize = static_cast<int64_t>(std::stoull(strChunkSize, nullptr, 16));
|
||||
}
|
||||
catch (std::invalid_argument& err)
|
||||
{
|
||||
(void)err;
|
||||
// Server can return something like `\n\r\n` for a chunk of zero length data. This is
|
||||
// allowed by RFC. `stoull` will throw invalid_argument if there is not at least one hex
|
||||
// digit to be parsed. For those cases, we consider the response as zero-lenght.
|
||||
this->m_chunkSize = 0;
|
||||
}
|
||||
|
||||
if (this->m_chunkSize == 0)
|
||||
{ // Response with no content. end of chunk
|
||||
|
||||
@ -3,10 +3,10 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief The base class for testing a curl session.
|
||||
*
|
||||
* @brief The base class for testing a curl session.
|
||||
*
|
||||
* @remark The curl connection mock is defined here.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
@ -39,6 +39,12 @@ namespace Azure { namespace Core { namespace Test {
|
||||
SendBuffer,
|
||||
(Context const& context, uint8_t const* buffer, size_t bufferSize),
|
||||
(override));
|
||||
|
||||
/* This is a way to test we are calling the destructor
|
||||
* Adding an extra mock method that is called from the destructor
|
||||
*/
|
||||
MOCK_METHOD(void, DestructObj, ());
|
||||
virtual ~MockCurlNetworkConnection() { DestructObj(); }
|
||||
};
|
||||
|
||||
}}} // namespace Azure::Core::Test
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
using ::testing::_;
|
||||
using ::testing::DoAll;
|
||||
using ::testing::Return;
|
||||
using ::testing::ReturnRef;
|
||||
using ::testing::SetArrayArgument;
|
||||
|
||||
namespace Azure { namespace Core { namespace Test {
|
||||
@ -41,4 +42,40 @@ namespace Azure { namespace Core { namespace Test {
|
||||
|
||||
EXPECT_NO_THROW(session->Perform(Azure::Core::GetApplicationContext()));
|
||||
}
|
||||
|
||||
TEST_F(CurlSession, chunkResponseSizeZero)
|
||||
{
|
||||
// chunked response with no content and no size
|
||||
std::string response("HTTP/1.1 200 Ok\r\ntransfer-encoding: chunked\r\n\r\n\n\r\n");
|
||||
std::string host("sample-host");
|
||||
|
||||
// Can't mock the curMock directly from a unique ptr, heap allocate it first and then make a
|
||||
// unique ptr for it
|
||||
MockCurlNetworkConnection* curlMock = new MockCurlNetworkConnection();
|
||||
EXPECT_CALL(*curlMock, SendBuffer(_, _, _)).WillOnce(Return(CURLE_OK));
|
||||
EXPECT_CALL(*curlMock, ReadFromSocket(_, _, _))
|
||||
.WillOnce(DoAll(
|
||||
SetArrayArgument<1>(response.data(), response.data() + response.size()),
|
||||
Return(response.size())));
|
||||
EXPECT_CALL(*curlMock, GetHost()).WillRepeatedly(ReturnRef(host));
|
||||
EXPECT_CALL(*curlMock, updateLastUsageTime());
|
||||
EXPECT_CALL(*curlMock, DestructObj());
|
||||
|
||||
// Create the unique ptr to take care about memory free at the end
|
||||
std::unique_ptr<MockCurlNetworkConnection> uniqueCurlMock(curlMock);
|
||||
|
||||
// Simulate a request to be sent
|
||||
Azure::Core::Http::Url url("http://microsoft.com");
|
||||
Azure::Core::Http::Request request(Azure::Core::Http::HttpMethod::Get, url);
|
||||
|
||||
{
|
||||
// Create the session inside scope so it is released and the connection is moved to the pool
|
||||
auto session
|
||||
= std::make_unique<Azure::Core::Http::CurlSession>(request, std::move(uniqueCurlMock));
|
||||
|
||||
EXPECT_NO_THROW(session->Perform(Azure::Core::GetApplicationContext()));
|
||||
}
|
||||
// Clear the connections from the pool to invoke clean routine
|
||||
Azure::Core::Http::CurlConnectionPool::ConnectionPoolIndex.clear();
|
||||
}
|
||||
}}} // namespace Azure::Core::Test
|
||||
|
||||
Loading…
Reference in New Issue
Block a user