aws / aws/aws-sdk-cpp

Exception thrown in Aws::Http::CurlHttpClient::OverrideOptionsOnConnectionHandle leaves library in an invalid state

Aperta
#3,145 1 commento 0 reazioni 0 assegnatari Vedi su GitHub
Cmake feature-request p3
Lingua principale
C++
Stelle
2.2k
Fork
1.2k
Merge medio
4g 11h
PR unite (30g)
13

Descrizione

### Describe the bug

When subclassing from Aws::Http::CurlHttpClient and overriding OverrideOptionsOnConnectionHandle, if this method throws an exception:
* The exception is propagated outside the call (so superficially it seems to work as expected)
* The destructor of the base class hangs (acquiring a lock)

### Expected Behavior

An exception, including STL exceptions, thrown from the method is handled in a way that cleans up the connection attempt appropriately

### Current Behavior

* Exception is propagated out as per standard C++ rules
* Subsequent destruction of the instance hangs

Relevant call stack:
```
aws-cpp-sdk-core.dll!std::condition_variable::wait(std::unique_lock & _Lck) Line 599 (c:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.35.32215\include\mutex:599)
aws-cpp-sdk-core.dll!std::condition_variable::wait(void)>(std::unique_lock & _Lck, Aws::Utils::ExclusiveOwnershipResourceManager::ShutdownAndWait::__l4::bool (void) _Pred) Line 605 (c:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.35.32215\include\mutex:605)
aws-cpp-sdk-core.dll!Aws::Utils::ExclusiveOwnershipResourceManager::ShutdownAndWait(unsigned __int64 resourceCount) Line 106 (c:\.conan\data\aws-sdk-cpp\1.11.116\CRSB\testing\source\src\aws-cpp-sdk-core\include\aws\core\utils\ResourceManager.h:106)
aws-cpp-sdk-core.dll!Aws::Http::CurlHandleContainer::~CurlHandleContainer() Line 28 (c:\.conan\data\aws-sdk-cpp\1.11.116\CRSB\testing\source\src\aws-cpp-sdk-core\source\http\curl\CurlHandleContainer.cpp:28)
aws-cpp-sdk-core.dll!Aws::Http::CurlHttpClient::~CurlHttpClient() (Unknown Source:0)
AgentCurlHttpClient_unit.exe!`AgentCurlHttpClientUnit::demo_failure::test_method'::`2'::TestCurlHttpClient::~TestCurlHttpClient() (Unknown Source:0)
```

### Reproduction Steps

Tested on Windows; setting the native CA option is required there to get the requests to succeed.

```
class TestCurlHttpClient: public Aws::Http::CurlHttpClient
{
public:
TestCurlHttpClient(const Aws::Client::ClientConfiguration& clientConfig): CurlHttpClient(clientConfig)
{
}

void OverrideOptionsOnConnectionHandle(CURL*curlhandle) const override
{
auto code = curl_easy_setopt(curlhandle, CURLoption::CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA);
if (code != CURLE_OK)
{
// failed to set native CA
throw std::runtime_error("Failed to set native CA");
return;
}
if (throw_exception)
{
throw std::exception("Demonstration");
}
}
bool throw_exception{false};
};

Aws::Client::ClientConfiguration config;

const char *endpoint = "https://www.google.com";
constexpr Aws::Http::HttpMethod method = Aws::Http::HttpMethod::HTTP_GET;
auto test_class(std::make_unique(config));

auto request_zero(Aws::Http::CreateHttpRequest(Aws::String(endpoint), method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod));

Aws::Http::CurlHttpClient basic_client_zero(config);
auto response_zero = test_class->MakeRequest(request_zero);
test_class.reset();

test_class = std::make_unique(config);
test_class->throw_exception = true;

auto request_one(Aws::Http::CreateHttpRequest(Aws::String(endpoint), method, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod));
std::shared_ptr response_one;
try
{
response_one = test_class->MakeRequest(request_one);
}
catch (const std::exception &e)
{
std::cout << "Exception caught as expected" << std::endl;
}

// Hangs.
test_class.reset();
```

### Possible Solution

```
try
{
OverrideOptionsOnConnectionHandle(handle);
}
catch (....)
{
// cleanup, including unlocking, and put in failure state
throw;
}
```

### Additional Information/Context

An official mechanism for `OverrideOptionsOnConnectionHandle` to report a failure would also help.

### AWS CPP SDK version used

1.11.116

### Compiler and Version used

Visual Studio 2022: Microsoft (R) C/C++ Optimizing Compiler Version 19.41.34123 for x64

### Operating System and version

Windows 11

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia con OverrideOptionsOnConnectionHandle e con il percorso di pulizia mostrato in CurlHandleContainer.cpp, quindi leggi ShutdownAndWait in include/aws/core/utils/ResourceManager.h. Riproduci il caso di eccezione su Windows usando l’esempio fornito di TestCurlHttpClient e verifica che la distruzione non rimanga più bloccata mentre l’eccezione resta osservabile.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
cpp
Ambito
networking
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.