From 1f312b2e42714ee80bec75a59662c448a8db1ed4 Mon Sep 17 00:00:00 2001 From: Max Kellermann <mk@cm4all.com> Date: Fri, 11 Dec 2020 14:13:53 +0100 Subject: [PATCH] curl/Handler: disallow OnData() to throw This eliminates some complexity from class CurlRequest. --- src/lib/curl/Handler.hxx | 2 +- src/lib/curl/Request.cxx | 19 +------------------ src/lib/curl/Request.hxx | 16 ---------------- test/RunCurl.cxx | 8 ++++++-- 4 files changed, 8 insertions(+), 37 deletions(-) diff --git a/src/lib/curl/Handler.hxx b/src/lib/curl/Handler.hxx index ad5001e11..1259c4b3a 100644 --- a/src/lib/curl/Handler.hxx +++ b/src/lib/curl/Handler.hxx @@ -59,7 +59,7 @@ public: /** * Response body data has been received. * - * May throw #Pause. + * May throw #Pause (but nothing else). */ virtual void OnData(ConstBuffer<void> data) = 0; diff --git a/src/lib/curl/Request.cxx b/src/lib/curl/Request.cxx index 1f1c59940..d174fdb80 100644 --- a/src/lib/curl/Request.cxx +++ b/src/lib/curl/Request.cxx @@ -47,9 +47,7 @@ CurlRequest::CurlRequest(CurlGlobal &_global, CurlResponseHandler &_handler) - :global(_global), handler(_handler), - postpone_error_event(global.GetEventLoop(), - BIND_THIS_METHOD(OnPostponeError)) + :global(_global), handler(_handler) { error_buffer[0] = 0; @@ -243,13 +241,6 @@ CurlRequest::DataReceived(const void *ptr, size_t received_size) noexcept return received_size; } catch (CurlResponseHandler::Pause) { return CURL_WRITEFUNC_PAUSE; - } catch (...) { - state = State::CLOSED; - /* move the CurlResponseHandler::OnError() call into a - "safe" stack frame */ - postponed_error = std::current_exception(); - postpone_error_event.Schedule(); - return CURL_WRITEFUNC_PAUSE; } } @@ -266,11 +257,3 @@ CurlRequest::WriteFunction(char *ptr, size_t size, size_t nmemb, return c.DataReceived(ptr, size); } - -void -CurlRequest::OnPostponeError() noexcept -{ - assert(postponed_error); - - handler.OnError(postponed_error); -} diff --git a/src/lib/curl/Request.hxx b/src/lib/curl/Request.hxx index abc2a46a7..654f3f179 100644 --- a/src/lib/curl/Request.hxx +++ b/src/lib/curl/Request.hxx @@ -31,11 +31,9 @@ #define CURL_REQUEST_HXX #include "Easy.hxx" -#include "event/DeferEvent.hxx" #include <map> #include <string> -#include <exception> struct StringView; class CurlGlobal; @@ -57,18 +55,6 @@ class CurlRequest final { std::multimap<std::string, std::string> headers; - /** - * An exception caught by DataReceived(), which will be - * forwarded into a "safe" stack frame by - * #postpone_error_event. This works around the - * problem that libcurl crashes if you call - * curl_multi_remove_handle() from within the WRITEFUNCTION - * (i.e. DataReceived()). - */ - std::exception_ptr postponed_error; - - DeferEvent postpone_error_event; - /** error message provided by libcurl */ char error_buffer[CURL_ERROR_SIZE]; @@ -167,8 +153,6 @@ private: void HeaderFunction(StringView s) noexcept; - void OnPostponeError() noexcept; - /** called by curl when new data is available */ static size_t _HeaderFunction(char *ptr, size_t size, size_t nmemb, void *stream) noexcept; diff --git a/test/RunCurl.cxx b/test/RunCurl.cxx index f81e8097e..6f5ce1a1f 100644 --- a/test/RunCurl.cxx +++ b/test/RunCurl.cxx @@ -50,8 +50,12 @@ public: } void OnData(ConstBuffer<void> data) override { - if (fwrite(data.data, data.size, 1, stdout) != 1) - throw std::runtime_error("Failed to write"); + try { + if (fwrite(data.data, data.size, 1, stdout) != 1) + throw std::runtime_error("Failed to write"); + } catch (...) { + OnError(std::current_exception()); + } } void OnEnd() override {