From 4b78cea3f727b8cc31d696c1253523921b4d4225 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 30 Aug 2015 23:22:39 +0100 Subject: Some better error handling in curl multi handle and runtime context --- libadhocutil/curlHandle.cpp | 1 + libadhocutil/curlMultiHandle.cpp | 2 ++ libadhocutil/curlStream.cpp | 3 +++ libadhocutil/runtimeContext.cpp | 6 +++++- libadhocutil/unittests/testCurl.cpp | 21 +++++++++++++++++++++ 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/libadhocutil/curlHandle.cpp b/libadhocutil/curlHandle.cpp index 3afd473..7912af7 100644 --- a/libadhocutil/curlHandle.cpp +++ b/libadhocutil/curlHandle.cpp @@ -13,6 +13,7 @@ CurlHandle::CurlHandle(const std::string & url) : postS(NULL), postE(NULL) { curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1); } CurlHandle::~CurlHandle() diff --git a/libadhocutil/curlMultiHandle.cpp b/libadhocutil/curlMultiHandle.cpp index ff509ce..4d5ca12 100644 --- a/libadhocutil/curlMultiHandle.cpp +++ b/libadhocutil/curlMultiHandle.cpp @@ -69,6 +69,8 @@ CurlMultiHandle::performAll() while ((msg = curl_multi_info_read(curlm, &msgs))) { if (msg->msg == CURLMSG_DONE) { curl_multi_remove_handle(curlm, msg->easy_handle); + running[msg->easy_handle]->res = msg->data.result; + running[msg->easy_handle]->SwapContext(); running.erase(msg->easy_handle); if (!curls.empty()) { addRunner(curlm, running, curls); diff --git a/libadhocutil/curlStream.cpp b/libadhocutil/curlStream.cpp index e31c99c..727aa21 100644 --- a/libadhocutil/curlStream.cpp +++ b/libadhocutil/curlStream.cpp @@ -16,6 +16,9 @@ CurlStreamSource::read(char * target, std::streamsize targetSize) if (!buflen) { SwapContext(); checkCurlCode(res); + if (!buflen) { + return 0; + } } size_t bytes = std::min(buflen, targetSize); memcpy(target, buf, bytes); diff --git a/libadhocutil/runtimeContext.cpp b/libadhocutil/runtimeContext.cpp index f4e12c2..731053a 100644 --- a/libadhocutil/runtimeContext.cpp +++ b/libadhocutil/runtimeContext.cpp @@ -26,7 +26,9 @@ RuntimeContext::SwapContext() swapcontext(&initial, &callback); } else { - swapcontext(&callback, &initial); + if (stack) { + swapcontext(&callback, &initial); + } } } @@ -34,5 +36,7 @@ void RuntimeContext::ccallback(RuntimeContext * rc) { rc->Callback(); + free(rc->stack); + rc->stack = nullptr; } diff --git a/libadhocutil/unittests/testCurl.cpp b/libadhocutil/unittests/testCurl.cpp index 41ee0a1..1c1f179 100644 --- a/libadhocutil/unittests/testCurl.cpp +++ b/libadhocutil/unittests/testCurl.cpp @@ -84,3 +84,24 @@ BOOST_AUTO_TEST_CASE( fetch_multi ) BOOST_REQUIRE_EQUAL("Curl", files["testCurl.cpp"]); } +BOOST_AUTO_TEST_CASE( fetch_multi_fail ) +{ + CurlMultiHandle cmh; + bool errored = false; + bool finished = false; + cmh.addCurl("http://sys.randomdan.homeip.net/missing", [&finished, &errored](auto & s) { + try { + std::string tok; + while (!s.eof()) { + s >> tok; + } + finished = true; + } catch (...) { + errored = true; + } + }); + cmh.performAll(); + BOOST_REQUIRE(!finished); + BOOST_REQUIRE(errored); +} + -- cgit v1.2.3